/*
 * 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.camel.component.milo.server;

import java.io.Closeable;
import java.io.File;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
import java.security.KeyPair;
import java.security.cert.X509Certificate;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.EnumSet;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Set;
import java.util.function.Supplier;

import org.apache.camel.Endpoint;
import org.apache.camel.component.milo.KeyStoreLoader;
import org.apache.camel.component.milo.server.internal.CamelNamespace;
import org.apache.camel.spi.annotations.Component;
import org.apache.camel.support.DefaultComponent;
import org.eclipse.milo.opcua.sdk.server.OpcUaServer;
import org.eclipse.milo.opcua.sdk.server.api.config.OpcUaServerConfig;
import org.eclipse.milo.opcua.sdk.server.api.config.OpcUaServerConfigBuilder;
import org.eclipse.milo.opcua.sdk.server.identity.AnonymousIdentityValidator;
import org.eclipse.milo.opcua.sdk.server.identity.IdentityValidator;
import org.eclipse.milo.opcua.sdk.server.identity.UsernameIdentityValidator;
import org.eclipse.milo.opcua.stack.core.StatusCodes;
import org.eclipse.milo.opcua.stack.core.UaException;
import org.eclipse.milo.opcua.stack.core.application.CertificateManager;
import org.eclipse.milo.opcua.stack.core.application.CertificateValidator;
import org.eclipse.milo.opcua.stack.core.application.DefaultCertificateManager;
import org.eclipse.milo.opcua.stack.core.application.DefaultCertificateValidator;
import org.eclipse.milo.opcua.stack.core.security.SecurityPolicy;
import org.eclipse.milo.opcua.stack.core.types.builtin.LocalizedText;
import org.eclipse.milo.opcua.stack.core.types.enumerated.UserTokenType;
import org.eclipse.milo.opcua.stack.core.types.structured.BuildInfo;
import org.eclipse.milo.opcua.stack.core.types.structured.UserTokenPolicy;

import static java.util.Collections.singletonList;
import static org.eclipse.milo.opcua.sdk.server.api.config.OpcUaServerConfig.USER_TOKEN_POLICY_ANONYMOUS;

/**
 * OPC UA Server based component
 */
@Component("milo-server")
public class MiloServerComponent extends DefaultComponent {
    public static final String DEFAULT_NAMESPACE_URI = "urn:org:apache:camel";

    private static final String URL_CHARSET = "UTF-8";
    private static final OpcUaServerConfig DEFAULT_SERVER_CONFIG;

    static {
        final OpcUaServerConfigBuilder cfg = OpcUaServerConfig.builder();

        cfg.setCertificateManager(new DefaultCertificateManager());
        cfg.setCertificateValidator(DenyAllCertificateValidator.INSTANCE);
        cfg.setSecurityPolicies(EnumSet.allOf(SecurityPolicy.class));
        cfg.setApplicationName(LocalizedText.english("Apache Camel Milo Server"));
        cfg.setApplicationUri("urn:org:apache:camel:milo:server");
        cfg.setProductUri("urn:org:apache:camel:milo");

        if (Boolean.getBoolean("org.apache.camel.milo.server.default.enableAnonymous")) {
            cfg.setUserTokenPolicies(singletonList(USER_TOKEN_POLICY_ANONYMOUS));
            cfg.setIdentityValidator(AnonymousIdentityValidator.INSTANCE);
        }

        DEFAULT_SERVER_CONFIG = cfg.build();
    }

    private static final class DenyAllCertificateValidator implements CertificateValidator {
        public static final CertificateValidator INSTANCE = new DenyAllCertificateValidator();

        private DenyAllCertificateValidator() {
        }

        @Override
        public void validate(final X509Certificate certificate) throws UaException {
            throw new UaException(StatusCodes.Bad_CertificateUseNotAllowed);
        }

        @Override
        public void verifyTrustChain(List<X509Certificate> certificateChain) throws UaException {
            throw new UaException(StatusCodes.Bad_CertificateUseNotAllowed);
        }
    }

    private String namespaceUri = DEFAULT_NAMESPACE_URI;

    private final OpcUaServerConfigBuilder serverConfig;

    private OpcUaServer server;
    private CamelNamespace namespace;

    private final Map<String, MiloServerEndpoint> endpoints = new HashMap<>();

    private Boolean enableAnonymousAuthentication;

    private Map<String, String> userMap;

    private String usernameSecurityPolicyUri = OpcUaServerConfig.USER_TOKEN_POLICY_USERNAME.getSecurityPolicyUri();

    private List<String> bindAddresses;

    private Supplier<CertificateValidator> certificateValidator;

    private final List<Runnable> runOnStop = new LinkedList<>();

    public MiloServerComponent() {
        this(DEFAULT_SERVER_CONFIG);
    }

    public MiloServerComponent(final OpcUaServerConfig serverConfig) {
        this.serverConfig = OpcUaServerConfig.copy(serverConfig != null ? serverConfig : DEFAULT_SERVER_CONFIG);
    }

    @Override
    protected void doStart() throws Exception {
        this.server = new OpcUaServer(buildServerConfig());

        this.namespace = this.server.getNamespaceManager().registerAndAdd(this.namespaceUri, index -> new CamelNamespace(index, this.namespaceUri, this.server));

        super.doStart();
        this.server.startup();
    }

    /**
     * Build the final server configuration, apply all complex configuration
     *
     * @return the new server configuration, never returns {@code null}
     */
    private OpcUaServerConfig buildServerConfig() {

        if (this.userMap != null || this.enableAnonymousAuthentication != null) {
            // set identity validator

            final Map<String, String> userMap = this.userMap != null ? new HashMap<>(this.userMap) : Collections.emptyMap();
            final boolean allowAnonymous = Boolean.TRUE.equals(this.enableAnonymousAuthentication);
            final IdentityValidator identityValidator = new UsernameIdentityValidator(allowAnonymous, challenge -> {
                final String pwd = userMap.get(challenge.getUsername());
                if (pwd == null) {
                    return false;
                }
                return pwd.equals(challenge.getPassword());
            });
            this.serverConfig.setIdentityValidator(identityValidator);

            // add token policies

            final List<UserTokenPolicy> tokenPolicies = new LinkedList<>();
            if (allowAnonymous) {
                tokenPolicies.add(OpcUaServerConfig.USER_TOKEN_POLICY_ANONYMOUS);
            }
            if (userMap != null) {
                tokenPolicies.add(getUsernamePolicy());
            }
            this.serverConfig.setUserTokenPolicies(tokenPolicies);
        }

        if (this.bindAddresses != null) {
            this.serverConfig.setBindAddresses(new ArrayList<>(this.bindAddresses));
        }

        if (this.certificateValidator != null) {
            final CertificateValidator validator = this.certificateValidator.get();
            log.debug("Using validator: {}", validator);
            if (validator instanceof Closeable) {
                runOnStop(() -> {
                    try {
                        log.debug("Closing: {}", validator);
                        ((Closeable)validator).close();
                    } catch (final IOException e) {
                        log.warn("Failed to close", e);
                    }
                });
            }
            this.serverConfig.setCertificateValidator(validator);
        }

        // build final configuration

        return this.serverConfig.build();
    }

    /**
     * Get the user token policy for using with username authentication
     * 
     * @return the user token policy to use for username authentication
     */
    private UserTokenPolicy getUsernamePolicy() {
        if (this.usernameSecurityPolicyUri == null || this.usernameSecurityPolicyUri.isEmpty()) {
            return OpcUaServerConfig.USER_TOKEN_POLICY_USERNAME;
        }
        return new UserTokenPolicy("username", UserTokenType.UserName, null, null, this.usernameSecurityPolicyUri);
    }

    private void runOnStop(final Runnable runnable) {
        this.runOnStop.add(runnable);
    }

    @Override
    protected void doStop() throws Exception {
        this.server.shutdown();
        super.doStop();

        this.runOnStop.forEach(runnable -> {
            try {
                runnable.run();
            } catch (final Exception e) {
                log.warn("Failed to run on stop", e);
            }
        });
        this.runOnStop.clear();
    }

    @Override
    protected Endpoint createEndpoint(final String uri, final String remaining, final Map<String, Object> parameters) throws Exception {
        synchronized (this) {
            if (remaining == null || remaining.isEmpty()) {
                return null;
            }

            MiloServerEndpoint endpoint = this.endpoints.get(remaining);

            if (endpoint == null) {
                endpoint = new MiloServerEndpoint(uri, remaining, this.namespace, this);
                setProperties(endpoint, parameters);
                this.endpoints.put(remaining, endpoint);
            }

            return endpoint;
        }
    }

    /**
     * The URI of the namespace, defaults to <code>urn:org:apache:camel</code>
     */
    public void setNamespaceUri(final String namespaceUri) {
        this.namespaceUri = namespaceUri;
    }

    /**
     * The application name
     */
    public void setApplicationName(final String applicationName) {
        Objects.requireNonNull(applicationName);
        this.serverConfig.setApplicationName(LocalizedText.english(applicationName));
    }

    /**
     * The application URI
     */
    public void setApplicationUri(final String applicationUri) {
        Objects.requireNonNull(applicationUri);
        this.serverConfig.setApplicationUri(applicationUri);
    }

    /**
     * The product URI
     */
    public void setProductUri(final String productUri) {
        Objects.requireNonNull(productUri);
        this.serverConfig.setProductUri(productUri);
    }

    /**
     * The TCP port the server binds to
     */
    public void setBindPort(final int port) {
        this.serverConfig.setBindPort(port);
    }

    /**
     * Set whether strict endpoint URLs are enforced
     */
    public void setStrictEndpointUrlsEnabled(final boolean strictEndpointUrlsEnforced) {
        this.serverConfig.setStrictEndpointUrlsEnabled(strictEndpointUrlsEnforced);
    }

    /**
     * Server name
     */
    public void setServerName(final String serverName) {
        this.serverConfig.setServerName(serverName);
    }

    /**
     * Server hostname
     */
    public void setHostname(final String hostname) {
        this.serverConfig.setServerName(hostname);
    }

    /**
     * Security policies
     */
    public void setSecurityPolicies(final Set<SecurityPolicy> securityPolicies) {
        if (securityPolicies == null || securityPolicies.isEmpty()) {
            this.serverConfig.setSecurityPolicies(EnumSet.noneOf(SecurityPolicy.class));
        } else {
            this.serverConfig.setSecurityPolicies(EnumSet.copyOf(securityPolicies));
        }
    }

    /**
     * Security policies by URI or name
     */
    public void setSecurityPoliciesById(final Collection<String> securityPolicies) {
        final EnumSet<SecurityPolicy> policies = EnumSet.noneOf(SecurityPolicy.class);

        if (securityPolicies != null) {
            for (final String policyName : securityPolicies) {
                final SecurityPolicy policy = SecurityPolicy.fromUriSafe(policyName).orElseGet(() -> SecurityPolicy.valueOf(policyName));
                policies.add(policy);
            }
        }

        this.serverConfig.setSecurityPolicies(policies);
    }

    /**
     * Security policies by URI or name
     */
    public void setSecurityPoliciesById(final String... ids) {
        if (ids != null) {
            setSecurityPoliciesById(Arrays.asList(ids));
        } else {
            setSecurityPoliciesById((Collection<String>)null);
        }
    }

    /**
     * Set user password combinations in the form of "user1:pwd1,user2:pwd2"
     * <p>
     * Usernames and passwords will be URL decoded
     * </p>
     */
    public void setUserAuthenticationCredentials(final String userAuthenticationCredentials) {
        if (userAuthenticationCredentials != null) {
            this.userMap = new HashMap<>();

            for (final String creds : userAuthenticationCredentials.split(",")) {
                final String[] toks = creds.split(":", 2);
                if (toks.length == 2) {
                    try {
                        this.userMap.put(URLDecoder.decode(toks[0], URL_CHARSET), URLDecoder.decode(toks[1], URL_CHARSET));
                    } catch (final UnsupportedEncodingException e) {
                        log.warn("Failed to decode user map entry", e);
                    }
                }
            }
        } else {
            this.userMap = null;
        }
    }

    /**
     * Enable anonymous authentication, disabled by default
     */
    public void setEnableAnonymousAuthentication(final boolean enableAnonymousAuthentication) {
        this.enableAnonymousAuthentication = enableAnonymousAuthentication;
    }

    /**
     * Set the {@link UserTokenPolicy} used when
     */
    public void setUsernameSecurityPolicyUri(final SecurityPolicy usernameSecurityPolicy) {
        this.usernameSecurityPolicyUri = usernameSecurityPolicy.getSecurityPolicyUri();
    }

    /**
     * Set the {@link UserTokenPolicy} used when
     */
    public void setUsernameSecurityPolicyUri(String usernameSecurityPolicyUri) {
        this.usernameSecurityPolicyUri = usernameSecurityPolicyUri;
    }

    /**
     * Set the addresses of the local addresses the server should bind to
     */
    public void setBindAddresses(final String bindAddresses) {
        if (bindAddresses != null) {
            this.bindAddresses = Arrays.asList(bindAddresses.split(","));
        } else {
            this.bindAddresses = null;
        }
    }

    /**
     * Server build info
     */
    public void setBuildInfo(final BuildInfo buildInfo) {
        this.serverConfig.setBuildInfo(buildInfo);
    }

    /**
     * Server certificate
     */
    public void setServerCertificate(final KeyStoreLoader.Result result) {
        /*
         * We are not implicitly deactivating the server certificate manager. If
         * the key could not be found by the KeyStoreLoader, it will return
         * "null" from the load() method. So if someone calls
         * setServerCertificate ( loader.load () ); he may, by accident, disable
         * the server certificate. If disabling the server certificate is
         * desired, do it explicitly.
         */
        Objects.requireNonNull(result, "Setting a null is not supported. call setCertificateManager(null) instead.)");
        setServerCertificate(result.getKeyPair(), result.getCertificate());
    }

    /**
     * Server certificate
     */
    public void setServerCertificate(final KeyPair keyPair, final X509Certificate certificate) {
        setCertificateManager(new DefaultCertificateManager(keyPair, certificate));
    }

    /**
     * Server certificate manager
     */
    public void setCertificateManager(final CertificateManager certificateManager) {
        if (certificateManager != null) {
            this.serverConfig.setCertificateManager(certificateManager);
        } else {
            this.serverConfig.setCertificateManager(new DefaultCertificateManager());
        }
    }

    /**
     * Validator for client certificates
     */
    public void setCertificateValidator(final Supplier<CertificateValidator> certificateValidator) {
        this.certificateValidator = certificateValidator;
    }

    /**
     * Validator for client certificates using default file based approach
     */
    public void setDefaultCertificateValidator(final File certificatesBaseDir) {
        this.certificateValidator = () -> new DefaultCertificateValidator(certificatesBaseDir);
    }
}
