package demo;

import java.io.File;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.Iterator;
import java.util.List;

import at.gv.egiz.pdfas.PdfAsFactory;
import at.gv.egiz.pdfas.api.PdfAs;
import at.gv.egiz.pdfas.api.analyze.AnalyzeParameters;
import at.gv.egiz.pdfas.api.analyze.AnalyzeResult;
import at.gv.egiz.pdfas.api.analyze.NonTextObjectInfo;
import at.gv.egiz.pdfas.api.commons.Constants;
import at.gv.egiz.pdfas.api.exceptions.PdfAsException;
import at.gv.egiz.pdfas.api.io.DataSource;
import at.gv.egiz.pdfas.api.verify.VerifyAfterAnalysisParameters;
import at.gv.egiz.pdfas.api.verify.VerifyResult;
import at.gv.egiz.pdfas.api.verify.VerifyResults;
import at.gv.egiz.pdfas.commandline.Main;
import at.gv.egiz.pdfas.framework.config.SettingsHelper;
import at.gv.egiz.pdfas.framework.vfilter.VerificationFilterParameters;
import at.gv.egiz.pdfas.io.FileBasedDataSource;

public class SignatureVerificationDemo {

   /**
    * Starts a demo that verifies a document.
    * 
    * @param args
    *           The parameter(s).
    */
   public static void main(String[] args) {

      if (args == null || args.length == 0) {
         System.err.println("Please provide path of file to be verified.");
         System.exit(1);
      }
      
      File configdir = new File("./work");
      File signedFile = new File(args[0]);

      try {

         // instantiate api
         PdfAs pdfasAPI = PdfAsFactory.createPdfAs(configdir);

         // set source
         DataSource dataSource = new FileBasedDataSource(signedFile, "application/pdf");

         // evaluate settings
         VerificationFilterParameters parameters = SettingsHelper.readVerificationFilterParametersFromSettings();
         String verifyMode = Constants.VERIFY_MODE_FULL_CONSERVATIVE;

         if (parameters.extractBinarySignaturesOnly()) {
            verifyMode = Constants.VERIFY_MODE_BINARY_ONLY;
         } else if (parameters.assumeOnlySignatureUpdateBlocks()) {
            verifyMode = Constants.VERIFY_MODE_SEMI_CONSERVATIVE;
         } else {
            verifyMode = Constants.VERIFY_MODE_FULL_CONSERVATIVE;
         }

         // configure analyze parameters
         AnalyzeParameters analyzeParameters = new AnalyzeParameters();
         analyzeParameters.setDocument(dataSource);
         analyzeParameters.setVerifyMode(verifyMode);
         analyzeParameters.setReturnNonTextualObjects(true);

         // analyze
         System.out.println("Analyzing...");
         AnalyzeResult analyzeResult = pdfasAPI.analyze(analyzeParameters);
         System.out.println("Successfully analyzed.");
         
         // setup verification
         VerifyAfterAnalysisParameters vaap = new VerifyAfterAnalysisParameters();
         vaap.setAnalyzeResult(analyzeResult);
         vaap.setReturnHashInputData(true);
         vaap.setSignatureDevice(Constants.SIGNATURE_DEVICE_MOA);
         vaap.setVerificationTime(null);

         // invoke verification
         System.out.println("Verifying...");
         VerifyResults verifyResults = pdfasAPI.verify(vaap);
         List verifyResultList = verifyResults.getResults();
         System.out.println("Verification complete.");

         // iterate over results
         PrintWriter out = new PrintWriter(System.out);
         Iterator it = verifyResultList.iterator();
         while (it.hasNext()) {
            VerifyResult result = (VerifyResult) it.next();
            Main.formatVerifyResult(result, out);
         }
         out.flush();
         
         // check if non textual elements have been detected
         if (analyzeResult.hasNonTextualObjects()) {
            System.out.println("\nWARNING: Non textual objects detected.");
            Iterator noit = analyzeResult.getNonTextualObjects().iterator();
            while (noit.hasNext()) {
               NonTextObjectInfo info = (NonTextObjectInfo) noit.next();
               System.out.println("  -> " + info.toString());
            }
            System.out.println();
         }
         
      } catch (PdfAsException e) {
         e.printStackTrace();
      } catch (IOException e) {
         e.printStackTrace();
      }

   }

}