using System;
using System.Diagnostics;
using System.IO;
using FirmaSAT;

// Some tests using the FirmaSAT .NET interface.
// Requires certain files to exist in the current working directory.

/* 
 **************************** COPYRIGHT NOTICE ****************************
 * Copyright (C) 2010 DI Management Services Pty Limited. 
 * All rights reserved. <www.di-mgt.com.au> <www.cryptosys.net>
 *   $Id: TestFirmaSat.cs $
 *   Last updated:
 *   $Date: 2010-01-12 17:37:00 $
 *   $Version: 2.0.0 $
 ************************* END OF COPYRIGHT NOTICE ************************
 */

namespace TestFirmaSATcsharp
{
    /// <summary>
    /// Test examples for FirmaSAT .NET interface
    /// </summary>
    class TestFirmaSATcsharp
    {
        /// <summary>
        /// The main entry point for the application.
        /// </summary>
        [STAThread]
        static void Main(string[] args)
        {
            int n;
            string s, s1;
            string fname;
            char ch;
            string attributeName, elementName;
            string newname, keyfile, password, certfile;

            Console.WriteLine("GENERAL METHODS:");
            Console.WriteLine("Interrogate the core diFirmaSat DLL:");
            n = FirmaSAT.General.Version();
            Console.WriteLine("Version={0}", n);
            s = General.CompileTime();
            Console.WriteLine("CompileTime={0}", s);
            s = General.ModuleName();
            Console.WriteLine("ModuleName={0}", s);
            ch = General.LicenceType();
            Console.WriteLine("LicenceType={0}", ch);

            Console.WriteLine("\nInterrogate the underlying CryptoSys PKI DLL:");
            n = FirmaSAT.General.PKIVersion();
            Console.WriteLine("PKIVersion={0}", n);
            s = General.PKICompileTime();
            Console.WriteLine("PKICompileTime={0}", s);
            s = General.PKIModuleName();
            Console.WriteLine("PKIModuleName={0}", s);

            Console.WriteLine("\nTRY VALIDATING XML FILES:");
            Console.WriteLine("1. A valid one:");
            fname = "Muestra_v2_signed2.xml";
            n = Sat.ValidateXml(fname);
            Console.WriteLine("Sat.ValidateXml('{0}') returns {1}", fname, n);
            Debug.Assert(n == 0, "Sat.ValidateXml failed");

            Console.WriteLine("2. An invalid one:");
            fname = "Muestra_v2_bad.xml";
            n = Sat.ValidateXml(fname);
            Console.WriteLine("Sat.ValidateXml('{0}') returns {1}", fname, n);
            s = Sat.LastError();
            Console.WriteLine("ErrorLookup({0})={1}", n, General.ErrorLookup(n));
            Console.WriteLine("LastError={0}", s);

            Console.WriteLine("\nFORM THE PIPESTRING FROM AN XML FILE:");
            fname = "Muestra_v2_signed2.xml";
            s = Sat.MakePipeStringFromXml(fname);
            Console.WriteLine("Sat.MakePipeStringFromXml('{0}')=\n{1}", fname, s);
            Debug.Assert(s.Length > 0, "Sat.MakePipeStringFromXml failed");

            Console.WriteLine("\nSIGN AN XML FILE:");
            fname = "Muestra_v2_base2.xml";
            newname = "Muestra_v2_signed_new.xml";
            keyfile = "aaa010101aaa_CSD_01.key";
            password = "a0123456789";   /* CAUTION: DO NOT HARD-CODE REAL PASSWORDS! */
            certfile = "aaa010101aaa_CSD_01.cer";
            n = Sat.SignXml(newname, fname, keyfile, password, certfile);
            Console.WriteLine("Sat.SignXml('{0}'-->'{1}') returns {2}", fname, newname, n);
            Debug.Assert(n == 0, "Sat.SignXml failed");
            // Did we make a valid XML file?
            n = Sat.ValidateXml(newname);
            Console.WriteLine("Sat.ValidateXml('{0}') returns {1}", newname, n);
            Debug.Assert(n == 0, "Sat.ValidateXml failed");

            Console.WriteLine("\nVERIFY A SIGNATURE IN AN XML FILE:");
            Console.WriteLine("1. One we know is good:");
            fname = "Muestra_v2_signed2.xml";
            n = Sat.VerifySignature(fname);
            Console.WriteLine("Sat.VerifySignature('{0}') returns {1}", fname, n);
            Debug.Assert(n == 0, "Sat.VerifySignature failed");

            Console.WriteLine("2. One we just made, so it should be good:");
            fname = newname;
            n = Sat.VerifySignature(fname);
            Console.WriteLine("Sat.VerifySignature('{0}') returns {1}", fname, n);
            Debug.Assert(n == 0, "Sat.VerifySignature failed");

            Console.WriteLine("\nFORM THE DIGEST OF THE PIPESTRING IN AN XML FILE:");
            fname = "Muestra_v2_signed2.xml";
            s = Sat.MakeDigestFromXml(fname);
            Console.WriteLine("Sat.MakeDigestFromXml('{0}')=\n{1}", fname, s);
            Debug.Assert(s.Length > 0, "Sat.MakeDigestFromXml failed");

            Console.WriteLine("\nEXTRACT THE DIGEST FROM THE SIGNATURE IN AN XML FILE:");
            fname = "Muestra_v2_signed2.xml";
            s = Sat.ExtractDigestFromSignature(fname);
            Console.WriteLine("Sat.ExtractDigestFromSignature('{0}')=\n{1}", fname, s);
            Debug.Assert(s.Length > 0, "Sat.ExtractDigestFromSignature failed");

            Console.WriteLine("\nEXTRACT AN ATTRIBUTE FROM AN XML FILE:");
            fname = "Muestra_v2_signed2.xml";
            elementName = "Comprobante";
            attributeName = "sello";
            s = Sat.GetXmlAttribute(fname, attributeName, elementName);
            Console.WriteLine("Sat.GetXmlAttribute('{0}',{2},{3})=\n{1}", fname, s, attributeName, elementName);
            Debug.Assert(s.Length > 0, "Sat.GetXmlAttribute failed");

            Console.WriteLine("\nGET DETAILS OF X.509 CERTIFICATE:");
            Console.WriteLine("1. From embedded `certificado` in XML");
            fname = "Muestra_v2_signed2.xml";
            s = Sat.GetCertNumber(fname);
            Console.WriteLine("Sat.GetCertNumber('{0}')={1}", fname, s);
            Debug.Assert(s.Length > 0, "Sat.GetCertNumber failed");
            s = Sat.GetCertExpiry(fname);
            Console.WriteLine("Sat.GetCertExpiry('{0}')={1}", fname, s);
            Debug.Assert(s.Length > 0, "Sat.GetCertExpiry failed");

            Console.WriteLine("2. From X.509 file");
            fname = "aaa010101aaa_CSD_01.cer";
            s = Sat.GetCertNumber(fname);
            Console.WriteLine("Sat.GetCertNumber('{0}')={1}", fname, s);
            Debug.Assert(s.Length > 0, "Sat.GetCertNumber failed");
            s = Sat.GetCertExpiry(fname);
            Console.WriteLine("Sat.GetCertExpiry('{0}')={1}", fname, s);
            Debug.Assert(s.Length > 0, "Sat.GetCertExpiry failed");

            Console.WriteLine("\nGET CERTIFICATE AS A BASE64 STRING:");
            fname = "aaa010101aaa_CSD_01.cer";
            s = Sat.GetCertAsString(fname);
            Console.WriteLine("Sat.GetCertAsString('{0}')=\n{1}", fname, s);
            Debug.Assert(s.Length > 0, "Sat.GetCertAsString failed");
            Console.WriteLine("Sat.GetCertAsString('{0}').Length={1}", fname, s.Length);
            // Compare against string from XML file
            fname = "Muestra_v2_signed2.xml";
            s1 = Sat.GetCertAsString(fname);
            Console.WriteLine("Sat.GetCertAsString('{0}').Length={1}", fname, s1.Length);
            Debug.Assert(s1.Length > 0, "Sat.GetCertAsString failed");
            Debug.Assert(String.Compare(s, s1, true) == 0, "Sat.GetCertAsString failed");

            Console.WriteLine("\nMAKE A SIGNATURE FROM A BASE XML FILE:");
            fname = "Muestra_v2_base2.xml";
            keyfile = "aaa010101aaa_CSD_01.key";
            password = "a0123456789";   /* CAUTION: DO NOT HARD-CODE REAL PASSWORDS! */
            s = Sat.MakeSignatureFromXml(fname, keyfile, password);
            Console.WriteLine("Sat.MakeSignatureFromXml('{0}')=\n{1}", fname, s);
            Debug.Assert(s.Length > 0, "Sat.MakeSignatureFromXml failed");

            Console.WriteLine("\nSIGN A DETALLISTA XML FILE:");
            fname = "detallista_base.xml";
            newname = "detallista-new-signed.xml";
            keyfile = "aaa010101aaa_CSD_01.key";
            password = "a0123456789";   /* CAUTION: DO NOT HARD-CODE REAL PASSWORDS! */
            certfile = "aaa010101aaa_CSD_01.cer";
            n = Sat.SignXml(newname, fname, keyfile, password, certfile);
            Console.WriteLine("Sat.SignXml('{0}'-->'{1}') returns {2}", fname, newname, n);
            Debug.Assert(n == 0, "Sat.SignXml failed");
            // Did we make a valid XML file?
            n = Sat.ValidateXml(newname);
            Console.WriteLine("Sat.ValidateXml('{0}') returns {1}", newname, n);
            Debug.Assert(n == 0, "Sat.ValidateXml failed");
            n = Sat.VerifySignature(newname);
            Console.WriteLine("Sat.VerifySignature('{0}') returns {1}", newname, n);
            Debug.Assert(n == 0, "Sat.VerifySignature failed");

            Console.WriteLine("\nEXTRACT AN ATTRIBUTE FROM A DETALLISTA XML FILE:");
            fname = "detallista-new-signed.xml";
            elementName = "detallista:detallista";
            attributeName = "documentStructureVersion";
            s = Sat.GetXmlAttribute(fname, attributeName, elementName);
            Console.WriteLine("Sat.GetXmlAttribute('{0}',{2},{3})={1}", fname, s, attributeName, elementName);
            Debug.Assert(s.Length > 0, "Sat.GetXmlAttribute failed");
            Debug.Assert(String.Compare(s, "AMC8.1") == 0, "Invalid detallista.documentStructureVersion");


            /*---
             Console.WriteLine("\nDISPLAY ALL POSSIBLE ERROR MESSAGES:");
             for (i = 0; i < 10000; i++)
             {
                 s = General.ErrorLookup(i);
                 if (s.Length > 0)
                     Console.WriteLine("{0}=>{1}", i, s);
             }
             ---*/

        }
    }
}