package net.catcert.psa.test.signature;

import java.math.BigInteger;
import java.security.cert.X509Certificate;

import net.catcert.psa.services.PsaServices;
import net.catcert.psa.util.Utils;

import org.etsi.uri._01903.v1_2_2.QualifierType;
import org.etsi.uri._01903.v1_2_2.QualifierType.Enum;

import schema.core._0._1.dss.tc.names.oasis.InternationalStringType;
import schema.core._0._1.dss.tc.names.oasis.ResultDocument.Result;

import com.sadiel.catcert.psa.ws.client.SignatureServiceStub;
import com.sadiel.catcert.psa.ws.client.factory.PSARequestFactory;
import com.sadiel.catcert.psa.ws.signature.InitSignDocumentAtPSADocument;
import com.sadiel.catcert.psa.ws.signature.InitSignDocumentAtPSAResponseDocument;
import com.sadiel.www.pdf.visiblesignature.v0_1.VisibleSignatureDataType;

import dss_directsign.profiles._0._1.psa.catcert.DocumentHashDocument.DocumentHash;
import dss_directsign.profiles._0._1.psa.catcert.DocumentOrDocumentHashType;
import dss_directsign.profiles._0._1.psa.catcert.DocumentType;
import dss_directsign.profiles._0._1.psa.catcert.Documents;
import dss_directsign.profiles._0._1.psa.catcert.InitSignDocumentAtPSARQSTDocument.InitSignDocumentAtPSARQST;
import dss_directsign.profiles._0._1.psa.catcert.MultiSignDocumentAtPSARSPNSDocument.MultiSignDocumentAtPSARSPNS;
import dss_directsign.profiles._0._1.psa.catcert.SignDocumentAtPSARSPNSDocument.SignDocumentAtPSARSPNS;
import dss_directsign.profiles._0._1.psa.catcert.SignedDocumentIdsDocument.SignedDocumentIds;


/**
 * Invokes multi init sign document at psa signature service
 * @author suport tčcnic CATCert
 *
 */
public class MultiInitSignDocumentAtPSASample {


	public static void main(String args[]){

		try{

			//política de procediment
			String functionalProcedureId = "PP-0004";

			//localització (idioma)
			String locale = "ES";

			//certificat de signatura
			String certFilePath = System.getProperty("user.dir")+"/resource/test/signature/SIGN_SegellOrgan_Ajuntament_Exemple.cer";
			X509Certificate keySelector = Utils.getX509Certificate(certFilePath);

			//documents a signar
			byte[][] documents = new byte[2][];
			//documents a signar
			//doc1
			String dataToSignFilePath = System.getProperty("user.dir")+"/resource/test/docs/prova.pdf";
			byte[] dataToSign = Utils.resourceAsBytes(dataToSignFilePath);
			documents[0] = dataToSign;
			//doc2
			dataToSignFilePath = System.getProperty("user.dir")+"/resource/test/docs/Prova2.pdf";
			byte[] dataToSign2 = Utils.resourceAsBytes(dataToSignFilePath);
			documents[1] = dataToSign2;

			//rol
			String role = null;

			//retorn d'informació
			boolean returnReport = true;
			boolean returnSignedDocument = true;
			boolean returnSignedDocumentId = true;

			//validació contra PSIS
			boolean psisValidation = false;

			//signature visible
			boolean showVisibleSignature = false;

			//configuració de la signatura visible
			VisibleSignatureDataType visibleSignatureData = null;

			//compromís
			String commitmentsSemantics = "Proof of origin indicates that the signer recognizes to have created, approved and sent the message";
			String commitmentsFieldOfApplication = "Aprovació genčrica"; 
			String identifierTypeValue = "urn:catcert:compromisos:signatura:aprovo";
			String oidTypeDescription = "Aprovació genčrica";

			Enum qualifierType = QualifierType.OID_AS_URN;

			//petició
			InitSignDocumentAtPSARQST request = PSARequestFactory._().createInitSignDocumentAtPSA(
					functionalProcedureId, 
					documents, 
					role, 
					oidTypeDescription, 
					commitmentsSemantics, 
					commitmentsFieldOfApplication, 
					identifierTypeValue, 
					qualifierType, 
					returnReport, 
					returnSignedDocument, 
					returnSignedDocumentId, 
					showVisibleSignature, 
					visibleSignatureData, 
					psisValidation);

			// petició multiple
			InitSignDocumentAtPSARQST[] requests = new InitSignDocumentAtPSARQST[1];
			requests[0] = request;
			BigInteger serialNumber = keySelector.getSerialNumber();
			String issuerName = Utils.getIssuerForPSARequest(keySelector);
			InitSignDocumentAtPSADocument multiInitSignDocAtPSARQST = PSARequestFactory._().createMultiInitSignDocumentAtPSA(locale, issuerName, serialNumber, requests);

			// servei de signatura
			SignatureServiceStub signatureServiceStub = PsaServices.getInstance().getSignatureServiceStub();

			//enviament de la petició
			InitSignDocumentAtPSAResponseDocument responseDoc = signatureServiceStub.initSignDocumentAtPSA(multiInitSignDocAtPSARQST);

			//resposta genčrica
			MultiSignDocumentAtPSARSPNS multiResponse = responseDoc.getInitSignDocumentAtPSAResponse().getMultiSignDocumentAtPSARSPNS();

			//resposta
			SignDocumentAtPSARSPNS response = multiResponse.getSignDocumentAtPSARSPNSArray()[0];

			//resultat de l'operació sol·licitada
			System.out.println("* Result:");
			Result result = response.getResult();
			String major = result.getResultMajor();
			String minor = result.getResultMinor();
			InternationalStringType message = result.getResultMessage();
			System.out.println("Major: "+major);
			System.out.println("Minor: "+minor);
			if(message!=null)
				System.out.println("Message: "+message.getStringValue());

			//identificador del context de signatura iniciat, necessari per les següents peticions associades al mateix context
			String procedureContextOid = response.getProcedureContextOID();
			System.out.println("* Procedure Context ID: "+procedureContextOid);

			//identificador del context de signatura
			String signatureActOid = response.getSignatureActOID();
			System.out.println("* Signature Act ID: "+signatureActOid);

			//reports
			Documents reports = response.getReportsDocuments();
			if(returnReport){
				if(reports!=null && reports.getDocumentArray()!=null){

					DocumentType[] documentArray = reports.getDocumentArray();
					for(int i=0;i<documentArray.length;i++){
						DocumentType report = documentArray[i];
						System.out.println("Report file name: "+report.getFilename());
						System.out.println("Report ID: "+report.getID());
						String reportFilePath = System.getProperty("user.dir")+"/resource/reports/"+report.getFilename() + ".pdf";
						Utils.writeDataToFile(reportFilePath, report.getData());
					}
				}
			}

			//documents signats
			DocumentOrDocumentHashType outDocs = response.getOutputDocuments();
			if(outDocs!=null){
				DocumentType[] outDocsArray = outDocs.getDocumentArray();
				DocumentHash[] outDocsHashArray = outDocs.getDocumentHashArray();
				System.out.println("* Documents:");
				if(outDocsArray!=null){
					for(int i=0;i<outDocsArray.length;i++){
						DocumentType doc = outDocsArray[i];
						System.out.println("Doc filename: "+doc.getFilename());
						System.out.println("Doc ID: "+doc.getID());
					}
				} else if(outDocsHashArray!=null){
					for(int i=0;i<outDocsHashArray.length;i++){
						DocumentHash doc = outDocsHashArray[i];
						System.out.println("Doc Hash ID: "+doc.getID());
						System.out.println("Doc Hash digest: "+doc.getDigestValue());
						System.out.println("Doc Hash algorithm: "+doc.getDigestMethod().getAlgorithm());
					}
				}
			}


			//id del document signat
			SignedDocumentIds signedDocsIds = response.getSignedDocumentIds();
			if(returnSignedDocument){
				System.out.println("* Signed Documents:");
				if(signedDocsIds!=null){
					String[] signedDocsList = signedDocsIds.getSignedDocumentIdArray();
					if(signedDocsList!=null){
						for(int i=0;i<signedDocsList.length;i++){
							String signedDoc = signedDocsList[i];
							System.out.println("Doc ID: "+signedDoc);
						}

					}
				}
			}

		} catch (Throwable e) {
			e.printStackTrace();
		}

	}	

}
