/*
 * 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.nifi.registry.web.api;

import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.module.jaxb.JaxbAnnotationIntrospector;
import org.apache.nifi.registry.client.NiFiRegistryClientConfig;
import org.apache.nifi.registry.properties.NiFiRegistryProperties;
import org.glassfish.jersey.client.ClientConfig;
import org.glassfish.jersey.jackson.internal.jackson.jaxrs.json.JacksonJaxbJsonProvider;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.test.context.TestConfiguration;
import org.springframework.boot.web.embedded.jetty.JettyServletWebServerFactory;
import org.springframework.boot.web.server.LocalServerPort;
import org.springframework.context.annotation.Bean;

import javax.annotation.PostConstruct;
import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.SSLContext;
import javax.ws.rs.client.Client;
import javax.ws.rs.client.ClientBuilder;
import java.io.FileReader;
import java.io.IOException;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantReadWriteLock;

/**
 * A base class to simplify creating integration tests against an API application running with an embedded server and volatile DB.
 */
public abstract class IntegrationTestBase {

    private static final String CONTEXT_PATH = "/nifi-registry-api";

    @TestConfiguration
    public static class TestConfigurationClass {

        /* REQUIRED: Any subclass extending IntegrationTestBase must add a Spring profile that defines a
         * property value for this key containing the path to the nifi-registy.properties file to use to
         * create a NiFiRegistryProperties Bean in the ApplicationContext.  */
        @Value("${nifi.registry.properties.file}")
        private String propertiesFileLocation;

        private final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
        private final Lock readLock = lock.readLock();
        private NiFiRegistryProperties testProperties;

        @Bean
        public JettyServletWebServerFactory jettyEmbeddedServletContainerFactory() {
            JettyServletWebServerFactory jettyContainerFactory = new JettyServletWebServerFactory();
            jettyContainerFactory.setContextPath(CONTEXT_PATH);
            return jettyContainerFactory;
        }

        @Bean
        public NiFiRegistryProperties getNiFiRegistryProperties() {
            readLock.lock();
            try {
                if (testProperties == null) {
                    testProperties = loadNiFiRegistryProperties(propertiesFileLocation);
                }
            } finally {
                readLock.unlock();
            }
            return testProperties;
        }

    }

    @Autowired
    private NiFiRegistryProperties properties;

    /* OPTIONAL: Any subclass that extends this base class MAY provide or specify a @TestConfiguration that provides a
     * NiFiRegistryClientConfig @Bean. The properties specified should correspond with the integration test cases in
     * the concrete subclass. See SecureFileIT for an example. */
    @Autowired(required = false)
    private NiFiRegistryClientConfig clientConfig;

    /* This will be injected with the random port assigned to the embedded Jetty container. */
    @LocalServerPort
    private int port;

    /**
     * Subclasses can access this auto-configured JAX-RS client to communicate to the NiFi Registry Server
     */
    protected Client client;

    @PostConstruct
    void initialize() {
        if (this.clientConfig != null) {
            this.client = createClientFromConfig(this.clientConfig);
        } else {
            this.client = ClientBuilder.newClient();
        }

    }

    /**
     * Subclasses can utilize this method to build a URL that has the correct protocol, hostname, and port
     * for a given path.
     *
     * @param relativeResourcePath the path component of the resource you wish to access, relative to the
     *                             base API URL, where the base includes the servlet context path.
     *
     * @return a String containing the absolute URL of the resource.
     */
    String createURL(String relativeResourcePath) {
        if (relativeResourcePath == null) {
            throw new IllegalArgumentException("Resource path cannot be null");
        }

        final StringBuilder baseUriBuilder = new StringBuilder(createBaseURL()).append(CONTEXT_PATH);

        if (!relativeResourcePath.startsWith("/")) {
            baseUriBuilder.append('/');
        }
        baseUriBuilder.append(relativeResourcePath);

        return baseUriBuilder.toString();
    }

    /**
     * Sub-classes can utilize this method to obtain the base-url for a client.
     *
     * @return a string containing the base url which includes the scheme, host, and port
     */
    String createBaseURL() {
        final boolean isSecure = this.properties.getSslPort() != null;
        final String protocolSchema = isSecure ? "https" : "http";

        final StringBuilder baseUriBuilder = new StringBuilder()
                .append(protocolSchema).append("://localhost:").append(port);

        return baseUriBuilder.toString();
    }

    NiFiRegistryClientConfig createClientConfig(String baseUrl) {
        final NiFiRegistryClientConfig.Builder builder = new NiFiRegistryClientConfig.Builder();
        builder.baseUrl(baseUrl);

        if (this.clientConfig != null) {
            if (this.clientConfig.getSslContext() != null) {
                builder.sslContext(this.clientConfig.getSslContext());
            }

            if (this.clientConfig.getHostnameVerifier() != null) {
                builder.hostnameVerifier(this.clientConfig.getHostnameVerifier());
            }
        }

        return builder.build();
    }

    /**
     * A helper method for loading NiFiRegistryProperties by reading *.properties files from disk.
     *
     * @param propertiesFilePath The location of the properties file
     * @return A NiFIRegistryProperties instance based on the properties file contents
     */
    static NiFiRegistryProperties loadNiFiRegistryProperties(String propertiesFilePath) {
        NiFiRegistryProperties properties = new NiFiRegistryProperties();
        try (final FileReader reader = new FileReader(propertiesFilePath)) {
            properties.load(reader);
        } catch (final IOException ioe) {
            throw new RuntimeException("Unable to load properties: " + ioe, ioe);
        }
        return properties;
    }

    private static Client createClientFromConfig(NiFiRegistryClientConfig registryClientConfig) {

        final ClientConfig clientConfig = new ClientConfig();
        clientConfig.register(jacksonJaxbJsonProvider());

        final ClientBuilder clientBuilder = ClientBuilder.newBuilder().withConfig(clientConfig);

        final SSLContext sslContext = registryClientConfig.getSslContext();
        if (sslContext != null) {
            clientBuilder.sslContext(sslContext);
        }

        final HostnameVerifier hostnameVerifier = registryClientConfig.getHostnameVerifier();
        if (hostnameVerifier != null) {
            clientBuilder.hostnameVerifier(hostnameVerifier);
        }

        return clientBuilder.build();
    }

    private static JacksonJaxbJsonProvider jacksonJaxbJsonProvider() {
        JacksonJaxbJsonProvider jacksonJaxbJsonProvider = new JacksonJaxbJsonProvider();

        ObjectMapper mapper = new ObjectMapper();
        mapper.setPropertyInclusion(JsonInclude.Value.construct(JsonInclude.Include.NON_NULL, JsonInclude.Include.NON_NULL));
        mapper.setAnnotationIntrospector(new JaxbAnnotationIntrospector(mapper.getTypeFactory()));
        // Ignore unknown properties so that deployed client remain compatible with future versions of NiFi Registry that add new fields
        mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);

        jacksonJaxbJsonProvider.setMapper(mapper);
        return jacksonJaxbJsonProvider;
    }

}
