/*
 * 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.brooklyn.entity.java;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.security.KeyPair;
import java.security.KeyStore;
import java.security.PrivateKey;
import java.security.cert.Certificate;
import java.security.cert.X509Certificate;

import org.apache.brooklyn.util.collections.MutableMap.Builder;
import org.apache.brooklyn.util.core.crypto.FluentKeySigner;
import org.apache.brooklyn.util.core.crypto.SecureKeys;
import org.apache.brooklyn.util.core.task.Tasks;
import org.apache.brooklyn.util.exceptions.Exceptions;
import org.apache.brooklyn.util.jmx.jmxmp.JmxmpAgent;
import org.apache.brooklyn.util.net.Urls;

import com.google.common.base.Preconditions;

public class JmxmpSslSupport {

    final static String BROOKLYN_VERSION = "0.8.0-incubating";  // BROOKLYN_VERSION (updated by script)
    
    private final JmxSupport jmxSupport;
    
    private KeyStore agentTrustStore;
    private KeyStore agentKeyStore;
    
    public JmxmpSslSupport(JmxSupport jmxSupport) {
        this.jmxSupport = Preconditions.checkNotNull(jmxSupport);
    }
    
    public String getJmxSslKeyStoreFilePath() {
        return Urls.mergePaths(jmxSupport.getRunDir(), "jmx-keystore");
    }
    
    public String getJmxSslTrustStoreFilePath() {
        return Urls.mergePaths(jmxSupport.getRunDir(), "jmx-truststore");
    }
    
    public void applyAgentJmxJavaSystemProperties(Builder<String, Object> result) {
        result.
            put(JmxmpAgent.USE_SSL_PROPERTY, true).
            put(JmxmpAgent.AUTHENTICATE_CLIENTS_PROPERTY, true).
            // the option below wants a jmxremote.password file; we use certs (above) to authenticate
            put("com.sun.management.jmxremote.authenticate", false);

        result.
            put(JmxmpAgent.JMXMP_KEYSTORE_FILE_PROPERTY, getJmxSslKeyStoreFilePath()).
            put(JmxmpAgent.JMXMP_TRUSTSTORE_FILE_PROPERTY, getJmxSslTrustStoreFilePath());
    }

    public FluentKeySigner getBrooklynRootSigner() {
        // TODO use brooklyn root CA keys etc
        return new FluentKeySigner("brooklyn-root");
    }

    /** builds remote keystores, stores config keys/certs, and copies necessary files across */
    public void install() {
        try {
            // build truststore and keystore
            FluentKeySigner signer = getBrooklynRootSigner();
            KeyPair jmxAgentKey = SecureKeys.newKeyPair();
            X509Certificate jmxAgentCert = signer.newCertificateFor("jmxmp-agent", jmxAgentKey);

            agentKeyStore = SecureKeys.newKeyStore();
            agentKeyStore.setKeyEntry("jmxmp-agent", jmxAgentKey.getPrivate(), 
                    // TODO jmx.ssl.agent.keyPassword
                    "".toCharArray(),
                    new Certificate[] { jmxAgentCert });
            ByteArrayOutputStream agentKeyStoreBytes = new ByteArrayOutputStream();
            agentKeyStore.store(agentKeyStoreBytes, 
                    // TODO jmx.ssl.agent.keyStorePassword
                    "".toCharArray());
            
            agentTrustStore = SecureKeys.newKeyStore();
            agentTrustStore.setCertificateEntry("brooklyn", getJmxAccessCert());
            ByteArrayOutputStream agentTrustStoreBytes = new ByteArrayOutputStream();
            agentTrustStore.store(agentTrustStoreBytes, "".toCharArray());
            
            // install the truststore and keystore and rely on JmxSupport to install the agent
            Tasks.setBlockingDetails("Copying keystore and truststore to the server.");
            try {
                jmxSupport.getMachine().get().copyTo(new ByteArrayInputStream(agentKeyStoreBytes.toByteArray()), getJmxSslKeyStoreFilePath());
                jmxSupport.getMachine().get().copyTo(new ByteArrayInputStream(agentTrustStoreBytes.toByteArray()), getJmxSslTrustStoreFilePath());
            } finally {
                Tasks.resetBlockingDetails();
            }

        } catch (Exception e) {
            throw Exceptions.propagate(e);
        }
    }

    public synchronized Certificate getJmxAccessCert() {
        Certificate cert = jmxSupport.getConfig(UsesJmx.JMX_SSL_ACCESS_CERT);
        if (cert!=null) return cert;
        // TODO load from keyStoreUrl
        KeyPair jmxAccessKey = SecureKeys.newKeyPair();
        X509Certificate jmxAccessCert = getBrooklynRootSigner().newCertificateFor("brooklyn-jmx-access", jmxAccessKey);

        jmxSupport.setConfig(UsesJmx.JMX_SSL_ACCESS_CERT, jmxAccessCert);
        jmxSupport.setConfig(UsesJmx.JMX_SSL_ACCESS_KEY, jmxAccessKey.getPrivate());
        
        return jmxAccessCert;
    }
    
    public synchronized PrivateKey getJmxAccessKey() {
        PrivateKey key = jmxSupport.getConfig(UsesJmx.JMX_SSL_ACCESS_KEY);
        if (key!=null) return key;
        getJmxAccessCert();
        return jmxSupport.getConfig(UsesJmx.JMX_SSL_ACCESS_KEY);
    }

}
