/*
* Copyright 2014 - LAit SpA
*				 Realizzato da Icona Management srl su commessa LAit SpA
* Copyright 2015- LAit SpA
*                                                  Aggiornato da LAit SpA
*
* Concesso in licenza a norma dell'EUPL, versione 1.1 o
* successive dell'EUPL (la "Licenza")- non appena saranno
* approvate dalla Commissione europea;
* Non è possibile utilizzare l'opera salvo nel rispetto della Licenza.
* È possibile ottenere una copia della Licenza al seguente indirizzo:
*
* http://ec.europa.eu/idabc/eupl
*
* Salvo diversamente indicato dalla legge applicabile o
* concordato per iscritto, il software distribuito secondo
* i termini della Licenza è distribuito "TAL QUALE",
* SENZA GARANZIE O CONDIZIONI DI ALCUN TIPO,
* esplicite o implicite.
* Si veda la Licenza per la lingua specifica che disciplina
* le autorizzazioni e le limitazioni secondo i termini della
* Licenza.
*/
/**
 * 
 */
package it.laitspa.cpf.service.lotto;

import it.gov.fatturapa.sdi.fatturapa.v1.CedentePrestatoreType;
import it.gov.fatturapa.sdi.fatturapa.v1.DatiTrasmissioneType;
import it.gov.fatturapa.sdi.fatturapa.v1.FatturaElettronicaHeaderType;
import it.gov.fatturapa.sdi.fatturapa.v1.FatturaElettronicaType;
import it.gov.fatturapa.sdi.fatturapa.v1.IdFiscaleType;
import it.laitspa.cpf.faces.utils.versionefattura.VersioneFatturaPaHelper;
import it.laitspa.cpf.model.sogei.inviofilesdi.AllegatoInvioFileSdiSogei;
import it.laitspa.cpf.model.sogei.inviofilesdi.TipoAllegatoInvioFileSdiSogei;
import it.laitspa.cpf.model.sogei.soggetto.SoggettoSogei;
import it.laitspa.cpf.model.sogei.statoinvio.StatoInvioSogei;
import it.laitspa.cpf.service.utils.WSUtils;
import it.laitspa.cpf.spring.lut.LUTFacade;
import it.laitspa.cpf.spring.sogei.SogeiFacade;
import it.laitspa.cpf.util.log.LogUtils;
import it.laitspa.xsd.resolver.XmlMarshaller;

import java.io.ByteArrayInputStream;
import java.io.InputStream;
import java.util.Date;
import java.util.List;

import javax.activation.DataHandler;
import javax.annotation.Resource;
import javax.jws.WebService;
import javax.xml.ws.BindingType;
import javax.xml.ws.WebServiceContext;
import javax.xml.ws.soap.SOAPBinding;

/**
 * @author andrea
 *
 */
@WebService(endpointInterface="it.laitspa.cpf.service.lotto.Lotto")
@BindingType(SOAPBinding.SOAP11HTTP_MTOM_BINDING)
public class LottoService
  implements Lotto
{

  @Resource
  WebServiceContext context;
  
  /* (non-Javadoc)
   * @see it.laitspa.cpf.service.lotto.Lotto#check()
   */
  @Override
  public String check()
  {
    return "Web services are running.";
  }
  
  @Override
  public LottoResponse uploadLotto(DataHandler b64)
  {
    LottoUploadResponse response = new LottoUploadResponse();
    response.setTipo(LottoResponseType.OK);
    
    SogeiFacade sdao = (SogeiFacade) WSUtils.findBean("SogeiFacade", context);
    
    LUTFacade ldao = (LUTFacade) WSUtils.findBean("LUTFacade", context);
    // Retrieve Soggetto sogei
    //
    SoggettoSogei soggetto = (SoggettoSogei) ldao.getItem("SoggettoSogei", SoggettoSogei.SOGGETTO_UNICO);
    if (soggetto != null)
    {
      
      // Parsing data.
      //
      StringBuilder sb = new StringBuilder();
      XmlMarshaller<FatturaElettronicaType> mr = new XmlMarshaller<FatturaElettronicaType>();
      mr.setBuffer(sb);
      
      // 
      // 
      byte[] data = WSUtils.getData(b64);
      ByteArrayInputStream bis = null;
      InputStream xsd = null;
      try
      {
        bis = new ByteArrayInputStream(data);
        xsd = VersioneFatturaPaHelper.getFileXSD(data);
        FatturaElettronicaType fattura = mr.unmarshal(FatturaElettronicaType.class, bis, xsd);
        if (mr.isHasErrors())
        {
          response.setTipo(LottoResponseType.ERRORE);
          response.getNote().add(sb.toString());
        }
        else
        {
          // Checking header
          //
          FatturaElettronicaHeaderType header = fattura.getFatturaElettronicaHeader();
          DatiTrasmissioneType trasmissione = header.getDatiTrasmissione();
          
          // IdFiscale must be the same of soggetto.
          //
          IdFiscaleType idFiscale = trasmissione.getIdTrasmittente();
          if (!idFiscale.getIdCodice().equals(soggetto.getCodiceIdentificativoFiscale()))
          {
            response.setTipo(LottoResponseType.ERRORE);
            response.getNote().add("Il codice identificativo del trasmittente non corrisponde con l'anagrafica presente sul sistema.");
            return response;
          }
          
          CedentePrestatoreType cedente = header.getCedentePrestatore();
          idFiscale = cedente.getDatiAnagrafici().getIdFiscaleIVA();
          if (!idFiscale.getIdCodice().equals(soggetto.getCodiceIdentificativoFiscale()))
          {
            response.setTipo(LottoResponseType.ERRORE);
            response.getNote().add("Il codice identificativo del cedente non corrisponde con l'anagrafica presente sul sistema.");
            return response;
          }
          
          // Serialize!!
          // 
          Integer codiceIdentificativo = sdao.serializeCaricamentoFlusso(null, SoggettoSogei.SOGGETTO_UNICO, fattura, StatoInvioSogei.IMMESSO);
          response.setIdentificativo(codiceIdentificativo);
          response.setTipo(LottoResponseType.OK);
          
          LogUtils.info(getClass(), "Flux successfully serialized.");
        }
        bis.close();
        xsd.close();
      }
      catch (Exception e)
      {
        LogUtils.error(getClass(), "Exception caugth while upload flux through web service.", e);
        response.setTipo(LottoResponseType.ERRORE);
        response.getNote().add("Errore durante il caricamento del flusso. Controllare il log applicativo.");
      }
    }
    else
    {
      response.setTipo(LottoResponseType.ERRORE);
      response.getNote().add("Anagrafica utente non presente.");
    }
    return response;
  }
  
  public LottoListResponse listLotti(Date dataCreazione)
  {
    LottoListResponse response = new LottoListResponse();
    response.setTipo(LottoResponseType.OK);
    
    /*
    if (codiceStato == null)
    {
      response.setTipo(LottoResponseType.ERRORE);
      response.getNote().add("Il codice stato non può essere nullo.");
      return response;
    }
    */
    
    SogeiFacade sdao = (SogeiFacade) WSUtils.findBean("SogeiFacade", context);
    List<Integer> list = sdao.listLottiByStateAndDate(dataCreazione, StatoInvioSogei.INVIATO);
    response.setIdentificativi(list);
    LogUtils.info(getClass(), "listLotti successfully invoked.");
    return response;
  }

  
  public LottoPrelievoResponse prelevaLotto(Integer identificativo)
  {
    DataHandler dh = null;
    LottoPrelievoResponse response = new LottoPrelievoResponse();
    response.setTipo(LottoResponseType.OK);
    
    SogeiFacade sdao = (SogeiFacade) WSUtils.findBean("SogeiFacade", context);
    AllegatoInvioFileSdiSogei allegato = sdao.retrieveAllegato(identificativo, TipoAllegatoInvioFileSdiSogei.LOTTO_NON_FIRMATO);
    if (allegato == null)
    {
      response.setTipo(LottoResponseType.ERRORE);
      response.getNote().add("Non esistono lotti corrispondenti al codice identificativo specificato.");
    }
    else
    {
      dh = WSUtils.toDataHandler(allegato.getDatafile());
      response.setIdentificativo(identificativo);
      response.setFile(dh);
    }
    LogUtils.info(getClass(), "prelevaLotto successfully invoked.");
    return response;
  }
  
  public LottoConfermaResponse confermaLotto(Integer identificativo)
  {
    LottoConfermaResponse response = new LottoConfermaResponse();
    response.setTipo(LottoResponseType.OK);
    response.setIdentificativo(identificativo);
    
    SogeiFacade sdao = (SogeiFacade) WSUtils.findBean("SogeiFacade", context);
    if (!sdao.confirmLotto(identificativo))
    {
      response.setTipo(LottoResponseType.ERRORE);
      response.getNote().add("Non è stato possibile aggiornare lo stato del flusso.");
    }
    
    return response;
  }

}
