/*
* 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.util.mail;

import java.util.Date;
import java.util.GregorianCalendar;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import org.w3c.dom.Document;
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;

public class PecUtils
{
  public static final int TIPO_ACCETTAZIONE = 1;
  public static final int TIPO_NON_ACCETTAZIONE = 2;
  public static final int TIPO_PRESA_IN_CARICO = 3;
  public static final int TIPO_AVVENUTA_CONSEGNA = 4;
  public static final int TIPO_POSTA_CERTIFICATA = 5;
  public static final int TIPO_ERRORE_CONSEGNA = 6;
  public static final int TIPO_PREAVVISO_ERRORE_CONSEGNA = 7;
  public static final int TIPO_RILEVAZIONE_VIRUS = 8;

  public static final int ERRORE_NESSUNO = 1;
  public static final int ERRORE_NO_DEST = 2;
  public static final int ERRORE_NO_DOMINIO = 3;
  public static final int ERRORE_VIRUS = 4;
  public static final int ERRORE_ALTRO = 5;

  
  public static int getTipoCertificato(Document daticert)
    throws Exception
  {
    // Retrieve outer node.
    //
    NodeList nl = daticert.getElementsByTagName("postacert");
    if(nl.getLength() != 1)
      throw new Exception("Main element postacert non found.");
    
    // Get tipo attribute.
    //
    Node node = nl.item(0);
    NamedNodeMap nnm = node.getAttributes();
    Node node_tipo = nnm.getNamedItem("tipo");
    if(node_tipo == null)
      throw new Exception("Attribute tipo non found.");
    String tipo = node_tipo.getNodeValue();
    
    if(tipo.equals("accettazione"))
      return TIPO_ACCETTAZIONE;
    else if(tipo.equals("non-accettazione"))
      return TIPO_NON_ACCETTAZIONE;
    else if(tipo.equals("presa-in-carico"))
      return TIPO_PRESA_IN_CARICO;
    else if(tipo.equals("avvenuta-consegna"))
      return TIPO_AVVENUTA_CONSEGNA;
    else if(tipo.equals("posta-certificata"))
      return TIPO_POSTA_CERTIFICATA;
    else if(tipo.equals("errore-consegna"))
      return TIPO_ERRORE_CONSEGNA;
    else if(tipo.equals("preavviso-errore-consegna"))
      return TIPO_PREAVVISO_ERRORE_CONSEGNA;
    else if(tipo.equals("rilevazione-virus"))
      return TIPO_RILEVAZIONE_VIRUS;
    else
      throw new Exception("Unexpected tipo found.");
  }

  
  public static int getErroreCertificato(Document daticert)
    throws Exception
  {
    // Retrieve outer node.
    //
    NodeList nl = daticert.getElementsByTagName("postacert");
    if(nl.getLength() != 1)
      throw new Exception("Main element postacert non found.");
    
    // Get errore attribute.
    //
    Node node = nl.item(0);
    NamedNodeMap nnm = node.getAttributes();
    Node node_errore = nnm.getNamedItem("errore");
    if(node_errore == null)
      return ERRORE_NESSUNO;
    String errore = node_errore.getNodeValue();
    
    if(errore.equals("nessuno"))
      return ERRORE_NESSUNO;
    else if(errore.equals("no-dest"))
      return ERRORE_NO_DEST;
    else if(errore.equals("no-dominio"))
      return ERRORE_NO_DOMINIO;
    else if(errore.equals("virus"))
      return ERRORE_VIRUS;
    else if(errore.equals("altro"))
      return ERRORE_ALTRO;
    else
      throw new Exception("Unexpected tipo found.");
  }
  
  
  public static String getMsgIdCertificato(Document daticert)
    throws Exception 
  {
    // Retrieve msgid node.
    //
    NodeList nl = daticert.getElementsByTagName("msgid");
    if(nl.getLength() != 1)
      throw new Exception("Element msgid non found.");
    Node msgid = nl.item(0);

    Node text = msgid.getFirstChild();
    if(text.getNodeType() != Node.TEXT_NODE)
      throw new Exception("No text found for element msgid.");
    
    return text.getNodeValue().trim();
  }
  
  
  public static String getIdentificativoCertificato(Document daticert)
    throws Exception 
  {
    // Retrieve identificativo node.
    //
    NodeList nl = daticert.getElementsByTagName("identificativo");
    if(nl.getLength() != 1)
      throw new Exception("Element identificativo non found.");
    Node identificativo = nl.item(0);

    Node text = identificativo.getFirstChild();
    if(text.getNodeType() != Node.TEXT_NODE)
      throw new Exception("No text found for element identificativo.");
    
    return text.getNodeValue().trim();
  }
  
  
  public static Date getDataCertificato(Document daticert)
    throws Exception
  {
    // Retrieve giorno node.
    //
    NodeList nl = daticert.getElementsByTagName("giorno");
    if(nl.getLength() != 1)
      throw new Exception("Element giorno non found.");
    Node giorno_node = nl.item(0);

    // Extract giorno node text.
    //
    Node text = giorno_node.getFirstChild();
    if(text.getNodeType() != Node.TEXT_NODE)
      throw new Exception("No text found for element giorno.");
    String giorno = text.getNodeValue().trim();
    
    // Retrieve ora node.
    //
    nl = daticert.getElementsByTagName("ora");
    if(nl.getLength() != 1)
      throw new Exception("Element ora non found.");
    Node ora_node = nl.item(0);

    // Extract ora node text.
    //
    text = ora_node.getFirstChild();
    if(text.getNodeType() != Node.TEXT_NODE)
      throw new Exception("No text found for element ora.");
    String ora = text.getNodeValue().trim();
   
    // Parse date.
    //
    Pattern p = Pattern.compile("^(\\d\\d)/(\\d\\d)/(\\d\\d\\d\\d)$");
    Matcher m = p.matcher(giorno);
    if(!m.find())
      throw new Exception("Unable to parse giorno element content.");
    int date = Integer.parseInt(m.group(1));
    int month = Integer.parseInt(m.group(2)) - 1;
    int year = Integer.parseInt(m.group(3));
    
    // Parse hour.
    //
    p = Pattern.compile("^(\\d\\d):(\\d\\d):(\\d\\d)$");
    m = p.matcher(ora);
    if(!m.find())
      throw new Exception("Unable to parse ora element content.");
    int hour = Integer.parseInt(m.group(1));
    int minute = Integer.parseInt(m.group(2));
    int second = Integer.parseInt(m.group(3));
    
    // Return date.
    //
    GregorianCalendar gc = new GregorianCalendar();
    gc.set(year, month, date, hour, minute, second);
    return gc.getTime();
  }
  
  
  public static String getDescrizioneErrore(int errore)
  {
    switch(errore)
    {
      case ERRORE_NESSUNO:
        return "Nessun errore";
        
      case ERRORE_NO_DEST:
        return "Destinatario errato";
        
      case ERRORE_NO_DOMINIO:
        return "Dominio errato";
        
      case ERRORE_VIRUS:
        return "Virus informatico";
        
      case ERRORE_ALTRO:
        return "Errore generico";
        
      default:
        throw new IllegalArgumentException("Unexpected errore value.");
    }
  }
  
  
  public static String getDescrizioneTipo(int tipo)
  {
    switch(tipo)
    {
      case TIPO_ACCETTAZIONE:
        return "Ricevuta di accettazione";
        
      case TIPO_NON_ACCETTAZIONE:
        return "Avviso di non accettazione";
        
      case TIPO_PRESA_IN_CARICO:
        return "Ricevuta di presa in carico";
        
      case TIPO_AVVENUTA_CONSEGNA:
        return "Ricevuta di avvenuta consegna";
        
      case TIPO_POSTA_CERTIFICATA:
        return "Messaggio di posta certificata";
        
      case TIPO_ERRORE_CONSEGNA:
        return "Avviso di mancata consegna";
        
      case TIPO_PREAVVISO_ERRORE_CONSEGNA:
        return "Preavviso di mancata consegna";
        
      case TIPO_RILEVAZIONE_VIRUS:
        return "Avviso di rilevazione virus informatico";
        
      default:
        throw new IllegalArgumentException("Unexpected tipo value.");
    }
  }
}