package org.esupportail.smsuapi.services.sms.impl.allmysms;

import org.apache.log4j.Logger;
import org.codehaus.jackson.JsonNode;

import org.esupportail.smsuapi.dao.DaoService;
import org.esupportail.smsuapi.dao.beans.Sms;
import org.esupportail.smsuapi.domain.beans.sms.SmsStatus;
import org.esupportail.smsuapi.domain.beans.sms.SMSBroker;
import org.esupportail.smsuapi.services.sms.ISMSSender;
import org.esupportail.smsuapi.services.sms.impl.smsenvoi.SMSSenderSmsenvoiImpl;

import javax.inject.Inject;

import org.springframework.beans.factory.annotation.Required;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpMethod;
import org.springframework.http.ResponseEntity;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
import org.springframework.web.client.RestTemplate;
import org.esupportail.smsuapi.utils.HttpUtils;

/**
 * Allmysms.com sender.
 */
public class SMSSenderAllmysms implements ISMSSender {

    protected final Logger logger = Logger.getLogger(getClass());

    protected boolean simulateMessageSending;
    private String account_login;
    private String account_apikey;

    protected String wsUrl;
    protected String simulate_wsUrl;

    private JsonNode from;

    @Inject
    private DaoService daoService;
    protected RestTemplate restTemplate;

    public synchronized void sendMessage(final SMSBroker sms) {
        try {
            if (logger.isDebugEnabled()) {
                final String messageISOLatin = new String(sms.message.getBytes(), "ISO-8859-1");
                logger.debug("sending encoded message : " + messageISOLatin);
            }

            AllmysmsRequest req = new AllmysmsRequest(sms.message, sms.rcpts, computeSenderlabel(sms));

            MultiValueMap<String, String> params = new LinkedMultiValueMap<>();
            params.add("login", account_login);
            params.add("apiKey", account_apikey);
            params.add("smsData", req.toJson());

            // restTemplate will use here jacksonHttpMessageConverter for response json->object
            ResponseEntity<AllmysmsResponse> respEntity = restTemplate.exchange(
                    simulateMessageSending ? simulate_wsUrl : wsUrl, HttpMethod.POST, new HttpEntity<>(params, null),
                    AllmysmsResponse.class);
            AllmysmsResponse resp = respEntity.getBody();
            logger.info("allmysms response " + resp.toString());
            save_message_id(sms, resp);
        } catch (Throwable t) {
            logger.error("An error occurs sending SMS " + sms.message, t);
            for (SMSBroker.Rcpt s : sms.rcpts) {
                logger.error(" to " + s.id + " - recipient : " + s.recipient + " - message : " + sms.message);
            }
        }

    }

    private void save_message_id(SMSBroker sms, AllmysmsResponse response) {
      int i = 0;
      for (SMSBroker.Rcpt s : sms.rcpts) {
        Sms smsDB = daoService.getSms(s.id);

        if (response.status == null || response.status != 100) {
            logger.error("allmysend send failed: " + response);
            smsDB.setStateAsEnum(SmsStatus.ERROR);
        }

        if (response.smsIds != null) {
            AllmysmsResponse.SmsId respIds = response.smsIds.get(i++);
            smsDB.setBrokerId(respIds.smsId);
        }

        daoService.updateSms(smsDB);
    }
    }

    private String computeSenderlabel(SMSBroker sms) {
        return SMSSenderSmsenvoiImpl.computeSenderlabel(logger, from, sms.accountLabel);
    }

    @Required
    public void setSimulateMessageSending(final boolean simulateMessageSending) {
        this.simulateMessageSending = simulateMessageSending;
    }

    @Required
    public void setSendsms_url(String wsUrl) {
        this.wsUrl = wsUrl;
    }

    @Required
    public void setSimulate_sendsms_url(String simulate_wsUrl) {
        this.simulate_wsUrl = simulate_wsUrl;
    }

    @Required
    public void setRestTemplate(RestTemplate restTemplate) {
        this.restTemplate = restTemplate;
    }

    public void setFrom_mapJSON(String from_mapJSON) {
        this.from = HttpUtils.json_decode(from_mapJSON);
        if (this.from == null)
            logger.error("invalid from_mapJSON: " + from_mapJSON);
    }

    @Required
    public void setAccount_login(String account_login) {
        this.account_login = account_login;
    }

    @Required
    public void setAccount_apikey(String account_apikey) {
        this.account_apikey = account_apikey;
    }

}

@@ -474,16 +474,90 @@
 iImpl;%0A%0A
+import java.util.Arrays;%0Aimport java.util.HashSet;%0Aimport java.util.Set;%0A%0A
 import j
@@ -2949,24 +2949,208 @@
 response) %7B%0A
+      Set%3CString%3E invalidNumbers = new HashSet%3C%3E(Arrays.asList(%0A            response.invalidNumbers != null ? response.invalidNumbers.split(%22%5C%5C%7C%22) : new String%5B%5D %7B%7D%0A      ));%0A        %0A
       int i 
@@ -3154,16 +3154,16 @@
  i = 0;%0A
-
       fo
@@ -3424,33 +3424,145 @@
 RROR);%0A        %7D
-%0A
+ else if (invalidNumbers.contains(smsDB.getPhone())) %7B%0A            smsDB.setStateAsEnum(SmsStatus.ERROR_POST_BL);
 %0A        if (res
@@ -3546,32 +3546,39 @@
 ST_BL);%0A        
+%7D else 
 if (response.sms
@@ -3588,24 +3588,134 @@
  != null) %7B%0A
+            logger.debug(%22getting response for %22 + smsDB.getPhone() + %22, it should be #%22 + i + %22 in smsIds%22);%0A
             

handle "invalidNumbers"