/*
 * Copyright 2001-2013 The Apache Software Foundation.
 * 
 * Licensed 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.juddi.v3.client.cli;

import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.util.Scanner;
import java.util.concurrent.atomic.AtomicReference;
import javax.xml.bind.JAXB;

import org.apache.juddi.v3.client.config.UDDIClient;
import org.apache.juddi.v3.client.cryptor.DigSigUtil;
import org.apache.juddi.v3.client.transport.Transport;
import org.uddi.api_v3.*;
import org.uddi.v3_service.UDDIInquiryPortType;
import org.uddi.v3_service.UDDIPublicationPortType;
import org.uddi.v3_service.UDDISecurityPortType;

/**
 * This class shows you how to digital sign a business and save to file
 *
 * @author <a href="mailto:alexoree@apache.org">Alex O'Ree</a>
 */
public class UddiDigitalSignatureFile {

        private static UDDIClient clerkManager = null;

        /**
         * This sets up the ws proxies using uddi.xml in META-INF
         */
        public UddiDigitalSignatureFile() {
                try {
                        // create a manager and read the config in the archive; 
                        // you can use your config file name
                        clerkManager = new UDDIClient("META-INF/simple-publish-uddi.xml");

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

        public enum UddiType {

                Business, Service, Binding, TModel, PublisherAssertion
        }

        public void Fire(String fileIn, String fileOut, UddiType type) {
                try {
                        System.out.println("WARN - All previous signatures will be removed!");
                        if (fileIn == null || fileOut == null || type == null) {
                                System.out.print("Input file: ");
                                fileIn = System.console().readLine();
                                System.out.print("Out file: ");
                                fileOut = System.console().readLine();
                                System.out.println();
                                for (int i = 0; i < UddiType.values().length; i++) {
                                        System.out.println("[" + i + "] " + UddiType.values()[i].toString());
                                }
                                System.out.print("UDDI Type: ");
                                String t = System.console().readLine();
                                type = UddiType.values()[Integer.parseInt(t)];
                        }

                        DigSigUtil ds = null;

                        //option 1), set everything manually
                        ds = new DigSigUtil();
                        ds.put(DigSigUtil.SIGNATURE_KEYSTORE_FILE, "keystore.jks");
                        ds.put(DigSigUtil.SIGNATURE_KEYSTORE_FILETYPE, "JKS");
                        ds.put(DigSigUtil.SIGNATURE_KEYSTORE_FILE_PASSWORD, "Test");
                        ds.put(DigSigUtil.SIGNATURE_KEYSTORE_KEY_ALIAS, "Test");
                        ds.put(DigSigUtil.SIGNATURE_OPTION_CERT_INCLUSION_BASE64, "true");

                        ds.put(DigSigUtil.SIGNATURE_OPTION_CERT_INCLUSION_SERIAL, "true");
                        ds.put(DigSigUtil.SIGNATURE_OPTION_CERT_INCLUSION_SUBJECTDN, "true");
                        ds.put(DigSigUtil.TRUSTSTORE_FILE, "truststore.jks");
                        ds.put(DigSigUtil.TRUSTSTORE_FILETYPE, "JKS");
                        ds.put(DigSigUtil.TRUSTSTORE_FILE_PASSWORD, "Test");

                        FileInputStream fis = new FileInputStream(fileIn);
                        Class expectedType = null;
                        switch (type) {
                                case Binding:
                                        expectedType = BindingTemplate.class;
                                        break;
                                case Business:
                                        expectedType = BusinessEntity.class;
                                        break;
                                case PublisherAssertion:
                                        expectedType = PublisherAssertion.class;
                                        break;
                                case Service:
                                        expectedType = BusinessService.class;
                                        break;
                                case TModel:
                                        expectedType = TModel.class;
                                        break;
                        }
                        Object be = JAXB.unmarshal(fis, expectedType);
                        fis.close();
                        fis = null;
                        
                        switch (type) {
                                case Binding:
                                        ((BindingTemplate)be).getSignature().clear();
                                        break;
                                case Business:
                                        ((BusinessEntity)be).getSignature().clear();
                                        break;
                                case PublisherAssertion:
                                        ((PublisherAssertion)be).getSignature().clear();
                                        break;
                                case Service:
                                        ((BusinessService)be).getSignature().clear();
                                        break;
                                case TModel:
                                        ((TModel)be).getSignature().clear();
                                        break;
                        }

                        System.out.println("signing");
                        Object signUDDI_JAXBObject = ds.signUddiEntity(be);
                        System.out.println("signed");
                        DigSigUtil.JAXB_ToStdOut(signUDDI_JAXBObject);
                        

                        System.out.println("verifing");
                        AtomicReference<String> msg = new AtomicReference<String>();
                        boolean verifySigned_UDDI_JAXB_Object = ds.verifySignedUddiEntity(signUDDI_JAXBObject, msg);
                        if (verifySigned_UDDI_JAXB_Object) {
                                System.out.println("signature validation passed (expected)");
                                FileOutputStream fos = new FileOutputStream(fileOut);
                                JAXB.marshal(signUDDI_JAXBObject, fos);
                                fos.close();
                        } else {
                                System.out.println("signature validation failed (not expected)");
                        }
                        System.out.println(msg.get());

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

       
}
