/*
 *   Copyright 2013 Brian Rosenberger (Brutex Network)
 *
 *   Licensed under the Apache License, Version 2.0 (the "License");
 *   you may not use this file except in compliance with the License.
 *   You may obtain a copy of the License at
 *
 *       http://www.apache.org/licenses/LICENSE-2.0
 *
 *   Unless required by applicable law or agreed to in writing, software
 *   distributed under the License is distributed on an "AS IS" BASIS,
 *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *   See the License for the specific language governing permissions and
 *   limitations under the License.
 */
package net.brutex.xservices.util;


import lombok.extern.slf4j.Slf4j;
import org.apache.http.HttpEntity;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.entity.EntityBuilder;
import org.apache.http.client.fluent.Request;
import org.apache.http.client.fluent.Response;
import org.apache.http.entity.ContentType;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.Reader;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
import java.util.concurrent.atomic.AtomicBoolean;


/**
 * Construct a HTTP POST and send it.
 *
 * @author Brian Rosenberger, bru(at)brutex.de
 * @since 0.1
 */
@Slf4j
public class SimpleSoap {

	private final String url;
	private final String soapBody;
	private final String id;
	private long duration = 0;


	final AtomicBoolean isInterrupted = new AtomicBoolean(false);
	
	/**
	 * Instantiates a new simple http event.
	 *
	 * @param url the url
	 * @param soapBody the soap body
	 */
	public SimpleSoap(String url, String id, String soapBody) {
		this.url = url;
		this.id = id;
		this.soapBody = soapBody;
	}

		/**
		 * Send soap.
		 *
		 * @param isDropResponse show interest in response or not
		 * @throws ClientProtocolException the client protocol exception
		 * @throws IOException             Signals that an I/O exception has occurred.
		 */
		public Reader sendSoap(boolean isDropResponse) {
			Reader response = null;
			long start = System.currentTimeMillis();

			HttpEntity entity = EntityBuilder.create()
					.setText(soapBody)
					.setContentType(ContentType.create("text/xml", StandardCharsets.UTF_8))
					.setContentEncoding("UTF-8")
					.build();

			log.trace("Sending event '{}' to target ALF Event Manager.", id);

			if(isInterrupted.get()) return null;

			try {
				Response resp = Request.Post(url)
						.addHeader("Accept", "text/xml")
						//.addHeader("Content-Type", "text/xml; charset=utf-8")
						.addHeader("SOAPAction", "")
						.body(entity).execute();

				if (!isDropResponse) {
					HttpEntity e = resp.returnResponse().getEntity();
					response = new BufferedReader(new InputStreamReader(e.getContent()));
					/*
					StringBuilder sb = new StringBuilder();
					BufferedReader in = new BufferedReader(new InputStreamReader(e.getContent()));
					String s;
					while ((s = in.readLine()) != null) {
						sb.append(s);
					}
					log.trace("Response: \n {}", sb.toString());
					if (sb.toString().contains("<soap:Fault>")) { return false;};
					if (! sb.toString().contains(":Envelope ")) { return false;};

					 */
				} else {
					log.debug("Response intentionally ignored.");
				}
			} catch (IOException e) {
				log.error("Error sending ALF Event '{}'. Got IOException: {}", id, e.getMessage());
            }

            duration = System.currentTimeMillis() - start;
			return response;
		}

	public void interrupt() {
		this.isInterrupted.set(true);
	}
}
