/*
 * 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.aries.containers;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.osgi.annotation.versioning.ProviderType;

/**
 * This class defines a service and it's settings. An instance is created via the
 * {@link Builder} and is immutable. For example to create a service for the Apache
 * Web Server docker image:
 * <pre>
 * ServiceConfig sc = ServiceConfig.builder("myservice", "httpd").
 *   cpu(0.5).memory(64).port(80).build();
 * </pre>
 */
@ProviderType
public class ServiceConfig {
    private final String[] commandLine;
    private final String containerImage;
    private final List<Integer> containerPorts;
    private final String entryPoint;
    private final Map<String, String> envVars;
//    private final List<HealthCheck> healthChecks; TODO add these!
    private final double requestedCPUunits;
    private final int requestedInstances;
    private final double requestedMemory; // in MiB
    private final String serviceName;

    private ServiceConfig(String[] commandLine, String containerImage, List<Integer> containerPorts, String entryPoint,
            Map<String, String> envVars, double requestedCPUunits, int requestedInstances, double requestedMemory,
            String serviceName) {
        this.commandLine = commandLine;
        this.containerImage = containerImage;
        this.containerPorts = Collections.unmodifiableList(containerPorts);
        this.entryPoint = entryPoint;
        this.envVars = Collections.unmodifiableMap(envVars);
        this.requestedCPUunits = requestedCPUunits;
        this.requestedInstances = requestedInstances;
        this.requestedMemory = requestedMemory;
        this.serviceName = serviceName;
    }

    /**
     * @return The command line to be used by the container. See also {@link #getEntryPoint()}.
     */
    public String[] getCommandLine() {
        return commandLine.clone();
    }

    /**
     * @return The name of the container image.
     */
    public String getContainerImage() {
        return containerImage;
    }

    /**
     * @return A list of the ports exposed externally.
     */
    public List<Integer> getContainerPorts() {
        return containerPorts;
    }

    /**
     * @return The entry point to be used with the image. Together with the {@link #getCommandLine()}
     * this defines the process run in the image.
     */
    public String getEntryPoint() {
        return entryPoint;
    }

    /**
     * @return A map containing all the environment variables to be set.
     */
    public Map<String, String> getEnvVars() {
        return envVars;
    }

    /**
     * @return The cpu units required for each container running this service.
     */
    public double getRequestedCpuUnits() {
        return requestedCPUunits;
    }

    /**
     * @return The number of replica containers requested for the service.
     */
    public int getRequestedInstances() {
        return requestedInstances;
    }

    /**
     * @return The amount of memory require for each container running the service.
     * Specified in million bytes (MiB).
     */
    public double getRequestedMemory() {
        return requestedMemory;
    }

    /**
     * The name of the service deployment. This has to be unique in the system.
     * @return The name of the service.
     */
    public String getServiceName() {
        return serviceName;
    }



    @Override
    public int hashCode() {
        final int prime = 31;
        int result = 1;
        result = prime * result + Arrays.hashCode(commandLine);
        result = prime * result + ((containerImage == null) ? 0 : containerImage.hashCode());
        result = prime * result + ((containerPorts == null) ? 0 : containerPorts.hashCode());
        result = prime * result + ((entryPoint == null) ? 0 : entryPoint.hashCode());
        result = prime * result + ((envVars == null) ? 0 : envVars.hashCode());
        long temp;
        temp = Double.doubleToLongBits(requestedCPUunits);
        result = prime * result + (int) (temp ^ (temp >>> 32));
        result = prime * result + requestedInstances;
        temp = Double.doubleToLongBits(requestedMemory);
        result = prime * result + (int) (temp ^ (temp >>> 32));
        result = prime * result + ((serviceName == null) ? 0 : serviceName.hashCode());
        return result;
    }

    @Override
    public boolean equals(Object obj) {
        if (this == obj)
            return true;
        if (obj == null)
            return false;
        if (getClass() != obj.getClass())
            return false;
        ServiceConfig other = (ServiceConfig) obj;
        if (!Arrays.equals(commandLine, other.commandLine))
            return false;
        if (containerImage == null) {
            if (other.containerImage != null)
                return false;
        } else if (!containerImage.equals(other.containerImage))
            return false;
        if (containerPorts == null) {
            if (other.containerPorts != null)
                return false;
        } else if (!containerPorts.equals(other.containerPorts))
            return false;
        if (entryPoint == null) {
            if (other.entryPoint != null)
                return false;
        } else if (!entryPoint.equals(other.entryPoint))
            return false;
        if (envVars == null) {
            if (other.envVars != null)
                return false;
        } else if (!envVars.equals(other.envVars))
            return false;
        if (Double.doubleToLongBits(requestedCPUunits) != Double.doubleToLongBits(other.requestedCPUunits))
            return false;
        if (requestedInstances != other.requestedInstances)
            return false;
        if (Double.doubleToLongBits(requestedMemory) != Double.doubleToLongBits(other.requestedMemory))
            return false;
        if (serviceName == null) {
            if (other.serviceName != null)
                return false;
        } else if (!serviceName.equals(other.serviceName))
            return false;
        return true;
    }

    /**
     * Obtain a service configuration builder.
     * @param serviceName The name for the service. This name should be unique in the
     * deployment, should be alphanum only and should not exceed 32 characters.
     * @param containerImage The container image to use. When using docker, this is
     * the docker image that should be used.
     * @return A service configuration builder
     */
    public static Builder builder(String serviceName, String containerImage) {
        return new Builder(serviceName, containerImage);
    }

    /** A builder for service configurations */
    @ProviderType
    public static class Builder {
        private String containerImage;
        private String[] commandLine = new String [] {};
        private Map<String, String> envMap = new HashMap<>();
        private String entryPoint;
        private double requestedCpuUnits = 0.5;
        private int requestedInstances = 1;
        private double requestedMemory = 64;
        private List<Integer> ports = new ArrayList<>();
        private String serviceName;

        Builder(String serviceName, String containerImage) {
            this.serviceName = serviceName;
            this.containerImage = containerImage;
        }

        /** The command line for the service. Also note that some images may need
         * an {@link #entryPoint(String)} specified in order to change behaviour.
         *
         * @param commandLine The command line to use.
         * @return the current builder for further building.
         */
        public Builder commandLine(String ... commandLine) {
            this.commandLine = commandLine;
            return this;
        }

        /**
         * The requested CPU for the service.
         *
         * @param requestedCpuUnits The requested CPU in CPU fractional units.
         * @return the current builder for further building.
         */
        public Builder cpu(double requestedCpuUnits) {
            this.requestedCpuUnits = requestedCpuUnits;
            return this;
        }

        /**
         * The entrypoint to use. Effectively the entrypoint together with the
         * commandline defines the process launched by the container.
         *
         * @param entryPoint The entry point to use.
         * @return the current builder for further building.
         */
        public Builder entryPoint(String entryPoint) {
            this.entryPoint = entryPoint;
            return this;
        }

        /**
         * Specify an environment variable. The variable is added to previously
         * specified environment variables and this builder method can be called
         * multiple times.
         *
         * @param name The variable name.
         * @param value The variable value.
         * @return the current builder for further building.
         */
        public Builder env(String name, String value) {
            this.envMap.put(name, value);
            return this;
        }

        /**
         * Set the environment variables to the provided map. This will replace
         * any previously specified environment variables.
         *
         * @param envMap The map of environment variables.
         * @return the current builder for further building.
         */
        public Builder env(Map<String, String> envMap) {
            this.envMap.clear();
            this.envMap.putAll(envMap);
            return this;
        }

        /**
         * Specify the number of container instances required for this service.
         * The container will be deployed as many times as specified here.
         *
         * @param requestedInstances The number of required instances.
         * @return the current builder for further building.
         */
        public Builder instances(int requestedInstances) {
            this.requestedInstances = requestedInstances;
            return this;
        }

        /**
         * Specify the required amount of memory in million bytes (MiB).
         *
         * @param requestedMemory The amount of memory required of a container.
         * @return the current builder for further building.
         */
        public Builder memory(double requestedMemory) {
            this.requestedMemory = requestedMemory;
            return this;
        }

        /**
         * Specify an external port to be exposed by the container. When a container
         * exposes multiple ports, call this builder method multiple times.
         *
         * @param port The port to be exposed externally.
         * @return the current builder for further building.
         */
        public Builder port(int port) {
            this.ports.add(port);
            return this;
        }

        /**
         * Build the configuration from the information gathered in the builder.
         *
         * @return An immutable service configuration.
         */
        public ServiceConfig build() {
            return new ServiceConfig(commandLine, containerImage, ports, entryPoint,
                    envMap, requestedCpuUnits, requestedInstances, requestedMemory,
                    serviceName);
        }
    }
}
