/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You 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 org.apache.camel.component.cm;

import java.io.BufferedReader;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.nio.charset.Charset;
import java.util.UUID;

import javax.xml.XMLConstants;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.transform.OutputKeys;
import javax.xml.transform.Result;
import javax.xml.transform.Source;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerException;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;

import org.w3c.dom.DOMImplementation;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Text;

import org.apache.camel.component.cm.exceptions.CMDirectException;
import org.apache.camel.component.cm.exceptions.XMLConstructionException;
import org.apache.camel.component.cm.exceptions.cmresponse.CMResponseException;
import org.apache.camel.component.cm.exceptions.cmresponse.InsufficientBalanceException;
import org.apache.camel.component.cm.exceptions.cmresponse.InvalidProductTokenException;
import org.apache.camel.component.cm.exceptions.cmresponse.NoAccountFoundForProductTokenException;
import org.apache.camel.component.cm.exceptions.cmresponse.UnknownErrorException;
import org.apache.camel.component.cm.exceptions.cmresponse.UnroutableMessageException;
import org.apache.http.HttpResponse;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.HttpClientBuilder;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class CMSenderOneMessageImpl implements CMSender {

    private static final Logger LOG = LoggerFactory.getLogger(CMSenderOneMessageImpl.class);

    private final String url;
    private final UUID productToken;

    public CMSenderOneMessageImpl(final String url, final UUID productToken) {

        this.url = url;
        this.productToken = productToken;
    }

    /**
     * Sends a message to CM endpoints. 1. CMMessage instance is going to be marshalled to xml. 2. Post request xml string to CMEndpoint.
     */
    @Override
    public void send(final CMMessage cmMessage) {

        // See: Check https://dashboard.onlinesmsgateway.com/docs for responses

        // 1.Construct XML. Throws XMLConstructionException
        final String xml = createXml(cmMessage);

        // 2. Try to send to CM SMS Provider ...Throws CMResponseException
        doHttpPost(url, xml);
    }

    private String createXml(final CMMessage message) {

        try {

            final ByteArrayOutputStream xml = new ByteArrayOutputStream();
            final DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
            factory.setFeature(XMLConstants.FEATURE_SECURE_PROCESSING, true);
            factory.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true);
            factory.setNamespaceAware(true);

            // Get the DocumentBuilder
            final DocumentBuilder docBuilder = factory.newDocumentBuilder();

            // Create blank DOM Document
            final DOMImplementation impl = docBuilder.getDOMImplementation();
            final Document doc = impl.createDocument(null, "MESSAGES", null);

            // ROOT Element es MESSAGES
            final Element root = doc.getDocumentElement();

            // AUTHENTICATION element
            final Element authenticationElement = doc.createElement("AUTHENTICATION");
            final Element productTokenElement = doc.createElement("PRODUCTTOKEN");
            authenticationElement.appendChild(productTokenElement);
            final Text productTokenValue = doc.createTextNode("" + productToken);
            productTokenElement.appendChild(productTokenValue);
            root.appendChild(authenticationElement);

            // MSG Element
            final Element msgElement = doc.createElement("MSG");
            root.appendChild(msgElement);

            // <FROM>VALUE</FROM>
            final Element fromElement = doc.createElement("FROM");
            fromElement.appendChild(doc.createTextNode(message.getSender()));
            msgElement.appendChild(fromElement);

            // <BODY>VALUE</BODY>
            final Element bodyElement = doc.createElement("BODY");
            bodyElement.appendChild(doc.createTextNode(message.getMessage()));
            msgElement.appendChild(bodyElement);

            // <TO>VALUE</TO>
            final Element toElement = doc.createElement("TO");
            toElement.appendChild(doc.createTextNode(message.getPhoneNumber()));
            msgElement.appendChild(toElement);

            // <DCS>VALUE</DCS> - if UNICODE - messageOut.isGSM338Enc
            // false
            if (message.isUnicode()) {
                final Element dcsElement = doc.createElement("DCS");
                dcsElement.appendChild(doc.createTextNode("8"));
                msgElement.appendChild(dcsElement);
            }

            // <REFERENCE>VALUE</REFERENCE> -Alfanum
            final String id = message.getIdAsString();
            if (id != null && !id.isEmpty()) {
                final Element refElement = doc.createElement("REFERENCE");
                refElement.appendChild(doc.createTextNode("" + message.getIdAsString()));
                msgElement.appendChild(refElement);
            }

            // <MINIMUMNUMBEROFMESSAGEPARTS>1</MINIMUMNUMBEROFMESSAGEPARTS>
            // <MAXIMUMNUMBEROFMESSAGEPARTS>8</MAXIMUMNUMBEROFMESSAGEPARTS>
            if (message.isMultipart()) {
                final Element minMessagePartsElement = doc.createElement("MINIMUMNUMBEROFMESSAGEPARTS");
                minMessagePartsElement.appendChild(doc.createTextNode("1"));
                msgElement.appendChild(minMessagePartsElement);

                final Element maxMessagePartsElement = doc.createElement("MAXIMUMNUMBEROFMESSAGEPARTS");
                maxMessagePartsElement.appendChild(doc.createTextNode(Integer.toString(message.getMultiparts())));
                msgElement.appendChild(maxMessagePartsElement);
            }

            // Creatate XML as String
            TransformerFactory transformerFactory = TransformerFactory.newInstance();
            transformerFactory.setFeature(XMLConstants.FEATURE_SECURE_PROCESSING, Boolean.TRUE);
            final Transformer aTransformer = transformerFactory.newTransformer();
            aTransformer.setOutputProperty(OutputKeys.INDENT, "yes");
            final Source src = new DOMSource(doc);
            final Result dest = new StreamResult(xml);
            aTransformer.transform(src, dest);
            return xml.toString();
        } catch (final TransformerException e) {
            throw new XMLConstructionException(String.format("Cant serialize CMMessage %s", message), e);
        } catch (final ParserConfigurationException e) {
            throw new XMLConstructionException(String.format("Cant serialize CMMessage %s", message), e);
        }
    }

    private void doHttpPost(final String urlString, final String requestString) {

        final HttpClient client = HttpClientBuilder.create().build();
        final HttpPost post = new HttpPost(urlString);
        post.setEntity(new StringEntity(requestString, Charset.forName("UTF-8")));

        try {

            final HttpResponse response = client.execute(post);

            final int statusCode = response.getStatusLine().getStatusCode();

            LOG.debug("Response Code : {}", statusCode);

            if (statusCode == 400) {
                throw new CMDirectException("CM Component and CM API show some kind of inconsistency. "
                                            + "CM is complaining about not using a post method for the request. And this component only uses POST requests. What happens?");
            }

            if (statusCode != 200) {
                throw new CMDirectException("CM Component and CM API show some kind of inconsistency. The component expects the status code to be 200 or 400. New api released? ");
            }

            // So we have 200 status code...

            // The response type is 'text/plain' and contains the actual
            // result of the request processing.

            // We obtaing the result text
            final BufferedReader rd = new BufferedReader(new InputStreamReader(response.getEntity().getContent()));

            final StringBuffer result = new StringBuffer();
            String line = null;
            while ((line = rd.readLine()) != null) {
                result.append(line);
            }

            // ... and process it

            line = result.toString();
            if (!line.isEmpty()) {

                // Line is not empty = error
                LOG.debug("Result of the request processing: FAILED\n{}", line);

                // The response text contains the error description. We will
                // throw a custom exception for each.

                if (line.contains(CMConstants.ERROR_UNKNOWN)) {
                    throw new UnknownErrorException();
                } else if (line.contains(CMConstants.ERROR_NO_ACCOUNT)) {
                    throw new NoAccountFoundForProductTokenException();
                } else if (line.contains(CMConstants.ERROR_INSUFICIENT_BALANCE)) {
                    throw new InsufficientBalanceException();
                } else if (line.contains(CMConstants.ERROR_UNROUTABLE_MESSAGE)) {
                    throw new UnroutableMessageException();
                } else if (line.contains(CMConstants.ERROR_INVALID_PRODUCT_TOKEN)) {
                    throw new InvalidProductTokenException();
                } else {

                    // SO FAR i would expect other kind of ERROR.

                    // MSISDN correctness and message validity is client
                    // responsibility
                    throw new CMResponseException("CHECK ME. I am not expecting this. ");
                }
            }

            // Ok. Line is EMPTY - successfully submitted
            LOG.debug("Result of the request processing: Successfully submited");
        } catch (final IOException io) {
            throw new CMDirectException(io);
        } catch (Throwable t) {
            if (!(t instanceof CMDirectException)) {
                // Chain it
                t = new CMDirectException(t);
            }
            throw (CMDirectException) t;
        }
    }
}
