/**
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements. See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership. The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License. You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied. See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */
package org.apache.xml.security.samples.signature;

import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.security.KeyStore;
import java.security.PrivateKey;
import java.security.cert.X509Certificate;

import org.apache.xml.security.keys.content.RetrievalMethod;
import org.apache.xml.security.keys.content.X509Data;
import org.apache.xml.security.keys.content.x509.XMLX509Certificate;
import org.apache.xml.security.keys.content.x509.XMLX509IssuerSerial;
import org.apache.xml.security.keys.content.x509.XMLX509SubjectName;
import org.apache.xml.security.samples.utils.resolver.OfflineResolver;
import org.apache.xml.security.signature.Manifest;
import org.apache.xml.security.signature.ObjectContainer;
import org.apache.xml.security.signature.Reference;
import org.apache.xml.security.signature.SignatureProperties;
import org.apache.xml.security.signature.SignatureProperty;
import org.apache.xml.security.signature.SignedInfo;
import org.apache.xml.security.signature.XMLSignature;
import org.apache.xml.security.transforms.Transforms;
import org.apache.xml.security.transforms.params.XPathContainer;
import org.apache.xml.security.utils.Constants;
import org.apache.xml.security.utils.ElementProxy;
import org.apache.xml.security.utils.JavaUtils;
import org.apache.xml.security.utils.XMLUtils;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;

/**
 *
 * @author $Author$
 */
public class CreateMerlinsExampleSixteen {

    static org.slf4j.Logger log =
        org.slf4j.LoggerFactory.getLogger(CreateMerlinsExampleSixteen.class);

    static {
        org.apache.xml.security.Init.init();
    }

    /**
     * Method main
     *
     * @param unused
     * @throws Exception
     */
    public static void main(String unused[]) throws Exception {
        ElementProxy.setDefaultPrefix(Constants.SignatureSpecNS, "ds");
        String keystoreType = "JKS";
        String keystoreFile = "samples/data/keystore.jks";
        String keystorePass = "xmlsecurity";
        String privateKeyAlias = "test";
        String privateKeyPass = "xmlsecurity";
        String certificateAlias = "test";
        File signatureFile = new File("build/merlinsSixteenRecreatedNoRetrievalMethod.xml");

        KeyStore ks = KeyStore.getInstance(keystoreType);
        FileInputStream fis = new FileInputStream(keystoreFile);

        ks.load(fis, keystorePass.toCharArray());

        PrivateKey privateKey =
            (PrivateKey) ks.getKey(privateKeyAlias, privateKeyPass.toCharArray());

        if (privateKey == null) {
            throw new RuntimeException("Private key is null");
        }

        X509Certificate cert =
            (X509Certificate) ks.getCertificate(certificateAlias);
        javax.xml.parsers.DocumentBuilderFactory dbf =
            javax.xml.parsers.DocumentBuilderFactory.newInstance();

        dbf.setNamespaceAware(true);

        javax.xml.parsers.DocumentBuilder db = dbf.newDocumentBuilder();
        org.w3c.dom.Document doc = db.newDocument();

        //////////////////////////////////////////////////
        Element envelope = doc.createElementNS("http://www.usps.gov/", "Envelope");

        envelope.setAttributeNS(Constants.NamespaceSpecNS, "xmlns", "http://www.usps.gov/");
        envelope.setAttributeNS(Constants.NamespaceSpecNS, "xmlns:foo", "http://www.usps.gov/foo");
        envelope.appendChild(doc.createTextNode("\n"));
        doc.appendChild(doc.createComment(" Preamble "));
        doc.appendChild(envelope);
        doc.appendChild(doc.createComment(" Postamble "));

        Element dearSir = doc.createElementNS("http://www.usps.gov/", "DearSir");

        dearSir.appendChild(doc.createTextNode("foo"));
        envelope.appendChild(dearSir);
        envelope.appendChild(doc.createTextNode("\n"));

        Element body = doc.createElementNS("http://www.usps.gov/", "Body");

        body.appendChild(doc.createTextNode("bar"));
        envelope.appendChild(body);
        envelope.appendChild(doc.createTextNode("\n"));

        Element YoursSincerely = doc.createElementNS("http://www.usps.gov/", "YoursSincerely");
        YoursSincerely.appendChild(doc.createTextNode("\n"));

        envelope.appendChild(YoursSincerely);

        Element PostScript = doc.createElementNS("http://www.usps.gov/", "PostScript");

        PostScript.appendChild(doc.createTextNode("bar"));
        envelope.appendChild(PostScript);

        Element Notaries = doc.createElementNS(null, "Notaries");

        Notaries.setAttributeNS(Constants.NamespaceSpecNS, "xmlns", "");
        Notaries.setAttributeNS(null, "Id", "notaries");
        Notaries.setIdAttributeNS(null, "Id", true);

        {
            Element Notary = doc.createElementNS(null, "Notary");

            Notary.setAttributeNS(null, "name", "Great, A. T.");
            Notaries.appendChild(Notary);
        }

        {
            Element Notary = doc.createElementNS(null, "Notary");

            Notary.setAttributeNS(null, "name", "Hun, A. T.");
            Notaries.appendChild(Notary);
        }

        envelope.appendChild(Notaries);
        envelope.appendChild(doc.createComment(" Commentary "));

        //////////////////////////////////////////////////
        String BaseURI = signatureFile.toURI().toURL().toString();
        XMLSignature sig =
            new XMLSignature(doc, BaseURI, XMLSignature.ALGO_ID_SIGNATURE_DSA);

        YoursSincerely.appendChild(sig.getElement());
        sig.setId("signature");

        /*
         * Add the Objects
         */

        // object-1
        {
            ObjectContainer object1 = new ObjectContainer(doc);

            object1.setId("object-1");
            object1.setMimeType("text/plain");
            object1.appendChild(doc.createTextNode("I am the text."));
            sig.appendObject(object1);
        }

        // object-2
        {
            ObjectContainer object2 = new ObjectContainer(doc);

            object2.setId("object-2");
            object2.setMimeType("text/plain");
            object2.setEncoding("http://www.w3.org/2000/09/xmldsig#base64");
            object2.appendChild(doc.createTextNode("SSBhbSB0aGUgdGV4dC4="));
            sig.appendObject(object2);
        }

        // object-3
        {
            ObjectContainer object = new ObjectContainer(doc);

            object.setId("object-3");

            Element nonc = doc.createElementNS(null, "NonCommentandus");

            nonc.setAttributeNS(Constants.NamespaceSpecNS, "xmlns", "");
            nonc.appendChild(doc.createComment(" Commentandum "));
            object.appendChild(doc.createTextNode("\n        "));
            object.appendChild(nonc);
            object.appendChild(doc.createTextNode("\n      "));
            sig.appendObject(object);
        }

        // object number 4
        {
            ObjectContainer object = new ObjectContainer(doc);

            object.appendChild(createObject4(sig));
            sig.appendObject(object);
        }

        // object number 4
        {
            ObjectContainer object = new ObjectContainer(doc);
            SignatureProperties sps = new SignatureProperties(doc);

            sps.setId("signature-properties-1");

            SignatureProperty sp = new SignatureProperty(doc, "#signature");
            Element signedAdress = doc.createElementNS("urn:demo",
            "SignedAddress");

            signedAdress.setAttributeNS(Constants.NamespaceSpecNS, "xmlns", "urn:demo");

            Element IP = doc.createElementNS("urn:demo", "IP");

            IP.appendChild(doc.createTextNode("192.168.21.138"));
            signedAdress.appendChild(IP);
            sp.appendChild(signedAdress);
            sps.addSignatureProperty(sp);
            object.appendChild(sps.getElement());
            sig.appendObject(object);
        }

        {
            ObjectContainer object = new ObjectContainer(doc);

            object.setId("object-4");

            X509Data x509data = new X509Data(doc);

            x509data.add(new XMLX509SubjectName(doc, cert));
            x509data.add(new XMLX509IssuerSerial(doc, cert));
            x509data.add(new XMLX509Certificate(doc, cert));
            object.appendChild(x509data.getElement());
            sig.appendObject(object);
        }

        /*
         * Add References
         */
        sig.getSignedInfo().addResourceResolver(
            new org.apache.xml.security.samples.utils.resolver.OfflineResolver());
        sig.addDocument("http://www.w3.org/TR/xml-stylesheet");

        {
            Transforms transforms = new Transforms(doc);

            transforms.addTransform(Transforms.TRANSFORM_BASE64_DECODE);
            sig.addDocument("http://xmldsig.pothole.com/xml-stylesheet.txt",
                            transforms, Constants.ALGO_ID_DIGEST_SHA1);
        }

        {
            Transforms transforms = new Transforms(doc);
            XPathContainer xpathC = new XPathContainer(doc);

            xpathC.setXPath("self::text()");
            transforms.addTransform(Transforms.TRANSFORM_XPATH,
                                    xpathC.getElementPlusReturns());
            sig.addDocument("#object-1", transforms,
                            Constants.ALGO_ID_DIGEST_SHA1, null,
            "http://www.w3.org/2000/09/xmldsig#Object");
        }

        {
            Transforms transforms = new Transforms(doc);

            transforms.addTransform(Transforms.TRANSFORM_BASE64_DECODE);
            sig.addDocument("#object-2", transforms,
                            Constants.ALGO_ID_DIGEST_SHA1, null,
            "http://www.w3.org/2000/09/xmldsig#Object");
        }

        sig.addDocument("#manifest-1", null, Constants.ALGO_ID_DIGEST_SHA1, null,
            "http://www.w3.org/2000/09/xmldsig#Manifest");
        sig.addDocument("#signature-properties-1", null,
                        Constants.ALGO_ID_DIGEST_SHA1, null,
        "http://www.w3.org/2000/09/xmldsig#SignatureProperties");

        {
            Transforms transforms = new Transforms(doc);

            transforms.addTransform(Transforms.TRANSFORM_ENVELOPED_SIGNATURE);
            sig.addDocument("", transforms, Constants.ALGO_ID_DIGEST_SHA1);
        }

        {
            Transforms transforms = new Transforms(doc);

            transforms.addTransform(Transforms.TRANSFORM_ENVELOPED_SIGNATURE);
            transforms.addTransform(Transforms.TRANSFORM_C14N_WITH_COMMENTS);
            sig.addDocument("", transforms, Constants.ALGO_ID_DIGEST_SHA1);
        }

        {
            Transforms transforms = new Transforms(doc);

            transforms.addTransform(Transforms.TRANSFORM_ENVELOPED_SIGNATURE);
            sig.addDocument("#xpointer(/)", transforms,
                            Constants.ALGO_ID_DIGEST_SHA1);
        }

        {
            Transforms transforms = new Transforms(doc);

            transforms.addTransform(Transforms.TRANSFORM_ENVELOPED_SIGNATURE);
            transforms.addTransform(Transforms.TRANSFORM_C14N_WITH_COMMENTS);
            sig.addDocument("#xpointer(/)", transforms,
                            Constants.ALGO_ID_DIGEST_SHA1);
        }

        {
            sig.addDocument("#object-3", null, Constants.ALGO_ID_DIGEST_SHA1,
                            null, "http://www.w3.org/2000/09/xmldsig#Object");
        }

        {
            Transforms transforms = new Transforms(doc);

            transforms.addTransform(Transforms.TRANSFORM_C14N_WITH_COMMENTS);
            sig.addDocument("#object-3", transforms,
                            Constants.ALGO_ID_DIGEST_SHA1, null,
                            "http://www.w3.org/2000/09/xmldsig#Object");
        }

        {
            sig.addDocument("#xpointer(id('object-3'))", null,
                            Constants.ALGO_ID_DIGEST_SHA1, null,
                            "http://www.w3.org/2000/09/xmldsig#Object");
        }

        {
            Transforms transforms = new Transforms(doc);

            transforms.addTransform(Transforms.TRANSFORM_C14N_WITH_COMMENTS);
            sig.addDocument("#xpointer(id('object-3'))", transforms,
                            Constants.ALGO_ID_DIGEST_SHA1, null,
                            "http://www.w3.org/2000/09/xmldsig#Object");
        }

        {
            sig.addDocument("#manifest-reference-1", null,
                            Constants.ALGO_ID_DIGEST_SHA1, "reference-1",
                            "http://www.w3.org/2000/09/xmldsig#Reference");
        }

        {
            sig.addDocument("#reference-1", null,
                            Constants.ALGO_ID_DIGEST_SHA1, "reference-2",
                            "http://www.w3.org/2000/09/xmldsig#Reference");
        }

        {
            sig.addDocument("#reference-2", null,
                            Constants.ALGO_ID_DIGEST_SHA1, null,
                            "http://www.w3.org/2000/09/xmldsig#Reference");
        }

        /*
         * Add KeyInfo and sign()
         */
        {
            Transforms retrievalTransforms = new Transforms(doc);
            XPathContainer xpathC = new XPathContainer(doc);

            xpathC.setXPathNamespaceContext("ds", Constants.SignatureSpecNS);
            xpathC.setXPath("ancestor-or-self::ds:X509Data");
            retrievalTransforms.addTransform(Transforms.TRANSFORM_XPATH, xpathC.getElement());
            sig.getKeyInfo().add(
                new RetrievalMethod(
                    doc, "#object-4", retrievalTransforms, "http://www.w3.org/2000/09/xmldsig#X509Data"));

            System.out.println("Start signing");
            sig.sign(privateKey);
            System.out.println("Finished signing");
        }

        FileOutputStream f = new FileOutputStream(signatureFile);

        XMLUtils.outputDOMc14nWithComments(doc, f);
        f.close();
        System.out.println("Wrote signature to " + BaseURI);

        SignedInfo s = sig.getSignedInfo();
        for (int i = 0; i < s.getLength(); i++) {
            Reference r = s.item(i);
            String fn = "build/merlin16_"+i+".html";
            System.out.println("Wrote Reference " + i + " to file " + fn);
            JavaUtils.writeBytesToFilename(fn, r.getHTMLRepresentation().getBytes());
        }

    }

    /**
     * Method createObject4
     *
     * @param sig
     *
     * @throws Exception
     */
    public static Element createObject4(XMLSignature sig) throws Exception {

        Document doc = sig.getElement().getOwnerDocument();
        String BaseURI = sig.getBaseURI();
        Manifest manifest = new Manifest(doc);
        manifest.addResourceResolver(new OfflineResolver());

        manifest.setId("manifest-1");
        manifest.addDocument(BaseURI, "http://www.w3.org/TR/xml-stylesheet",
                             null, Constants.ALGO_ID_DIGEST_SHA1,
                             "manifest-reference-1", null);
        manifest.addDocument(BaseURI, "#reference-1", null,
                             Constants.ALGO_ID_DIGEST_SHA1, null,
                             "http://www.w3.org/2000/09/xmldsig#Reference");

        String xslt = ""
            + "<xsl:stylesheet xmlns:xsl='http://www.w3.org/1999/XSL/Transform'\n"
            + "                xmlns='http://www.w3.org/TR/xhtml1/strict' \n"
            + "                exclude-result-prefixes='foo' \n"
            + "                version='1.0'>\n"
            + "  <xsl:output encoding='UTF-8' \n"
            + "              indent='no' \n"
            + "              method='xml' />\n"
            + "  <xsl:template match='/'>\n"
            + "    <html>\n"
            + "      <head>\n"
            + "        <title>Notaries</title>\n"
            + "      </head>\n"
            + "      <body>\n"
            + "        <table>\n"
            + "          <xsl:for-each select='Notaries/Notary'>\n"
            + "            <tr>\n"
            + "              <th>\n"
            + "                <xsl:value-of select='@name' />\n"
            + "              </th>\n"
            + "            </tr>\n"
            + "          </xsl:for-each>\n"
            + "        </table>\n"
            + "      </body>\n"
            + "    </html>\n"
            + "  </xsl:template>\n"
            + "</xsl:stylesheet>\n"
            ;

        javax.xml.parsers.DocumentBuilderFactory dbf =
            javax.xml.parsers.DocumentBuilderFactory.newInstance();

        dbf.setNamespaceAware(true);

        javax.xml.parsers.DocumentBuilder db = dbf.newDocumentBuilder();
        org.w3c.dom.Document docxslt =
            db.parse(new ByteArrayInputStream(xslt.getBytes()));
        Node xslElem = docxslt.getDocumentElement();
        Node xslElemImported = doc.importNode(xslElem, true);
        Transforms transforms = new Transforms(doc);

        transforms.addTransform(Transforms.TRANSFORM_XSLT,
                                (Element) xslElemImported);
        manifest.addDocument(BaseURI, "#notaries", transforms,
                             Constants.ALGO_ID_DIGEST_SHA1, null, null);

        return manifest.getElement();
    }

}
