package com.izenpe.signupdate.client.pades;

import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.Arrays;
import java.util.Date;
import java.util.List;

import org.oasis_open.docs.www.dss._2004._06.oasis_dss_1_0_core_schema_wd_27_xsd.OptionalOutputs;
import org.w3c.dom.Document;

import com.izenpe.zain.signupdate.SignupdateRequestSender;
import com.izenpe.zain.signupdate.SignupdateResponse;
import com.izenpe.zain.signupdate.constants.Language;
import com.izenpe.zain.signupdate.constants.SignatureProfile;
import com.izenpe.zain.signupdate.utils.XpathUtils;

public final class Pades {
	private static final String INPUT_PATH = "inputs\\prueba.pdf";
	private static final String OUTPUT_PATH = "outputs\\signedPrueba.pdf";
	private static final String END_POINT = "https://psf.izenpe.com:8443/trustedx-sgw/SignUpdateGateway";
	
	public static void main(String[] args) throws Exception {
		new Pades();
	}

	private Pades() throws Exception {
		// ====================================================================================================
		// LEEMOS EL FICHERO A FIRMAR
		// ====================================================================================================
		final InputStream inputStream = new FileInputStream(Pades.INPUT_PATH);
		final byte[] buff = new byte[inputStream.available()];
		inputStream.read(buff);
		inputStream.close();

		// ====================================================================================================
		// REALIZAMOS LA PETICION
		// ====================================================================================================
		final SignupdateResponse signupdateResponse 
				= SignupdateRequestSender
						.getSender()
							.setEndpoint(Pades.END_POINT)
							.setSignatureProfile(SignatureProfile.PADES)
							.setLanguage(Language.ES)
	//						.setZainSigner("DN")
							.setSignatureDocumentBytes(buff)
						.sendRequest();

		// ====================================================================================================
		// PROCESAMOS LA RESPUESTA
		// ====================================================================================================
		if (signupdateResponse.isValid()) {
			System.out.println("Se ha firmado el PDF de forma correcta ========================================");
			System.out.println("===============================================================================");

			// Firma ------------------------------------------------------------------------------------------
			final byte[] signature = signupdateResponse.getSignature();

			final OutputStream outputStream = new FileOutputStream(Pades.OUTPUT_PATH);
			outputStream.write(signature);
			outputStream.close();

			System.out.println("Firma guardada ----------------------------------------------------------------");
			System.out.println("");

			// Certificado ------------------------------------------------------------------------------------
			final Document[] certificates = signupdateResponse.getCertificates();
			for (int i = 0; i < certificates.length; i++) {
				System.out.println("Certificado obtenido ----------------------------------------------------------");

				final String numeroSerie = XpathUtils.getInstance().getValue(certificates[i], "/certificado/numeroSerie/text()");
				final String reconocido = XpathUtils.getInstance().getValue(certificates[i], "/certificado/reconocido/text()");
				final String politica = XpathUtils.getInstance().getValue(certificates[i], "/certificado/politica/text()");
				final String cn = XpathUtils.getInstance().getValue(certificates[i], "/certificado/cn/text()");
				final String subject = XpathUtils.getInstance().getValue(certificates[i], "/certificado/subject/text()");
				final String fechaDesde = XpathUtils.getInstance().getValue(certificates[i], "/certificado/validez/desde/text()");
				final String fechaHasta = XpathUtils.getInstance().getValue(certificates[i], "/certificado/validez/hasta/text()");
				final List<String> keyUsageList = XpathUtils.getInstance().getValueList(certificates[i], "/certificado/keyUsage/uso/text()");
				final List<String> extendedKeyUsageList = XpathUtils.getInstance().getValueList(certificates[i], "/certificado/extendedKeyUsage/uso/text()");

				System.out.println("Numero de serie: " + numeroSerie);
				System.out.println("Reconocido: " + reconocido);
				System.out.println("Política: " + politica);
				System.out.println("Nombre: " + cn);
				System.out.println("Subject: " + subject);
				System.out.println("Validez - Desde: " + fechaDesde);
				System.out.println("Validez - Hasta: " + fechaHasta);
				System.out.println("Key usage: " + Arrays.toString(keyUsageList.toArray()));
				System.out.println("Extended key usage: " + Arrays.toString(extendedKeyUsageList.toArray()));
				System.out.println("");
			}
			
			// Timestamp --------------------------------------------------------------------------------------
			final Date timestampDate = signupdateResponse.getTimestampDate();
			System.out.println("Timestamp obtenido ------------------------------------------------------------");
			System.out.println("Fecha: " + timestampDate);
			System.out.println("");
			
			OptionalOutputs optionalOutputs = signupdateResponse.getOptionalOutputs();
			System.out.println("Numero de firmas ------------------------------------------------------------");
			System.out.println("Cantidad: " + optionalOutputs.getNumberPdfSignatures());
			System.out.println("");
		} else {
			final String resultMajor = signupdateResponse.getResultMajor();
			final String resultMinor = signupdateResponse.getResultMinor();

			System.out.println("Se ha producido un error en la firma ==========================================");
			System.out.println("===============================================================================");
			System.out.println("Major: " + resultMajor);
			System.out.println("Minor: " + resultMinor);
			System.out.println("Message: " + signupdateResponse.getResultMessage());
			System.out.println("");
		}
	}
}
