// 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 com.cloud.consoleproxy;

import java.util.Arrays;
import java.util.Map;
import java.util.stream.Collectors;

import org.apache.cloudstack.framework.config.ConfigKey;

import com.cloud.deploy.DeploymentPlanner;
import com.cloud.exception.ConcurrentOperationException;
import com.cloud.exception.InsufficientCapacityException;
import com.cloud.exception.OperationTimedoutException;
import com.cloud.exception.ResourceUnavailableException;
import com.cloud.utils.component.Manager;
import com.cloud.vm.ConsoleProxyVO;
import com.cloud.vm.VirtualMachine;
import com.cloud.vm.VirtualMachineProfile;

public interface ConsoleProxyManager extends Manager, ConsoleProxyService {

    int DEFAULT_PROXY_CAPACITY = 50;
    int DEFAULT_STANDBY_CAPACITY = 10;
    int DEFAULT_PROXY_VM_RAMSIZE = 1024;            // 1G
    int DEFAULT_PROXY_VM_CPUMHZ = 500;                // 500 MHz

    int DEFAULT_PROXY_CMD_PORT = 8001;
    int DEFAULT_PROXY_VNC_PORT = 0;
    int DEFAULT_PROXY_URL_PORT = 80;
    int DEFAULT_PROXY_SESSION_TIMEOUT = 300000;        // 5 minutes

    String ALERT_SUBJECT = "proxy-alert";
    String CERTIFICATE_NAME = "CPVMCertificate";

    ConfigKey<Boolean> ConsoleProxySslEnabled = new ConfigKey<>(Boolean.class, "consoleproxy.sslEnabled",  ConfigKey.CATEGORY_ADVANCED, "false",
            "Enable SSL for console proxy", false, ConfigKey.Scope.Zone, null);

    ConfigKey<Boolean> NoVncConsoleDefault = new ConfigKey<>(Boolean.class, "novnc.console.default", ConfigKey.CATEGORY_ADVANCED, "true",
        "If true, noVNC console will be default console for virtual machines", false, ConfigKey.Scope.Zone, null);

    ConfigKey<Boolean> NoVncConsoleSourceIpCheckEnabled = new ConfigKey<>(ConfigKey.CATEGORY_ADVANCED, Boolean.class, "novnc.console.sourceip.check.enabled", "false",
        "If true, The source IP to access novnc console must be same as the IP in request to management server for console URL. Needs to reconnect CPVM to management server when this changes (via restart CPVM, or management server, or cloud service in CPVM)", false);

    ConfigKey<Boolean> NoVncConsoleShowDot = new ConfigKey<>(Boolean.class, "novnc.console.show.dot", ConfigKey.CATEGORY_ADVANCED, "true",
            "If true, in noVNC console a dot cursor will be shown when the remote server provides no local cursor, or provides a fully-transparent (invisible) cursor.",
            true, ConfigKey.Scope.Zone, null);

    ConfigKey<String> ConsoleProxyServiceOffering = new ConfigKey<>(String.class, "consoleproxy.service.offering", "Console Proxy", null,
            "Uuid of the service offering used by console proxy; if NULL - system offering will be used", true, ConfigKey.Scope.Zone, null);

    ConfigKey<String> ConsoleProxyCapacityStandby = new ConfigKey<>(String.class, "consoleproxy.capacity.standby", "Console Proxy", String.valueOf(DEFAULT_STANDBY_CAPACITY),
            "The minimal number of console proxy viewer sessions that system is able to serve immediately(standby capacity)", false, ConfigKey.Scope.Zone, null);

    ConfigKey<String> ConsoleProxyCapacityScanInterval = new ConfigKey<>(String.class, "consoleproxy.capacityscan.interval", "Console Proxy", "30000",
            "The time interval(in millisecond) to scan whether or not system needs more console proxy to ensure minimal standby capacity", false, null);

    ConfigKey<Boolean> ConsoleProxyRestart = new ConfigKey<>(Boolean.class, "consoleproxy.restart", "Console Proxy", "true",
            "Console proxy restart flag, defaults to true", true, ConfigKey.Scope.Zone, null);

    ConfigKey<String> ConsoleProxyUrlDomain = new ConfigKey<>(String.class, "consoleproxy.url.domain", "Console Proxy", "",
            "Console proxy url domain - domainName,privateip", false, ConfigKey.Scope.Zone, null);

    ConfigKey<Integer> ConsoleProxySessionMax = new ConfigKey<>(Integer.class, "consoleproxy.session.max", "Console Proxy", String.valueOf(DEFAULT_PROXY_CAPACITY),
            "The max number of viewer sessions console proxy is configured to serve for", true, ConfigKey.Scope.Zone, null);

    ConfigKey<Integer> ConsoleProxySessionTimeout = new ConfigKey<>(Integer.class, "consoleproxy.session.timeout", "Console Proxy", String.valueOf(DEFAULT_PROXY_SESSION_TIMEOUT),
            "Timeout(in milliseconds) that console proxy tries to maintain a viewer session before it times out the session for no activity", true, ConfigKey.Scope.Zone, null);

    ConfigKey<Boolean> ConsoleProxyDisableRpFilter = new ConfigKey<>(Boolean.class, "consoleproxy.disable.rpfilter", "Console Proxy", "true",
            "disable rp_filter on console proxy VM public interface", true, ConfigKey.Scope.Zone, null);

    ConfigKey<Long> ConsoleProxySessionReconnectionWindow = new ConfigKey<>(Long.class, "consoleproxy.session.reconnection.window", "Console Proxy", "0",
            "Reconnection window (in milliseconds) for client IPs to the same session on console proxy VM", true, ConfigKey.Scope.Zone, null);

    ConfigKey<Integer> ConsoleProxyLaunchMax = new ConfigKey<>(Integer.class, "consoleproxy.launch.max", "Console Proxy", "10",
            "maximum number of console proxy instances per zone can be launched", false, ConfigKey.Scope.Zone, null);

    String consoleProxyManagementStates = Arrays.stream(com.cloud.consoleproxy.ConsoleProxyManagementState.values()).map(Enum::name).collect(Collectors.joining(","));
    ConfigKey<String> ConsoleProxyServiceManagementState = new ConfigKey<String>(ConfigKey.CATEGORY_ADVANCED, String.class, "consoleproxy.management.state", com.cloud.consoleproxy.ConsoleProxyManagementState.Auto.toString(),
            "console proxy service management state", false, ConfigKey.Kind.Select, consoleProxyManagementStates);

    ConfigKey<String> ConsoleProxyManagementLastState = new ConfigKey<String>(ConfigKey.CATEGORY_ADVANCED, String.class, "consoleproxy.management.state.last", com.cloud.consoleproxy.ConsoleProxyManagementState.Auto.toString(),
            "last console proxy service management state", false, ConfigKey.Kind.Select, consoleProxyManagementStates);

    ConfigKey<String> ConsoleProxyVmUserData = new ConfigKey<>(String.class, "console.proxy.vm.userdata",
            ConfigKey.CATEGORY_ADVANCED, "",
            "UUID for user data for console proxy VMs. This works only when systemvm.userdata.enabled is set to true",
            true, ConfigKey.Scope.Zone, null, "User Data for CPVMs",
            null, ConfigKey.GROUP_SYSTEM_VMS, ConfigKey.SUBGROUP_CONSOLE_PROXY_VM);

    void setManagementState(ConsoleProxyManagementState state);

    ConsoleProxyManagementState getManagementState();

    void resumeLastManagementState();

    ConsoleProxyVO startProxy(long proxyVmId, boolean ignoreRestartSetting);

    void startProxyForHA(VirtualMachine vm, Map<VirtualMachineProfile.Param, Object> params, DeploymentPlanner planner)
            throws InsufficientCapacityException, ResourceUnavailableException, ConcurrentOperationException,
            OperationTimedoutException;

    boolean stopProxy(long proxyVmId);

    boolean rebootProxy(long proxyVmId);

    boolean destroyProxy(long proxyVmId);

    int getVncPort(Long dataCenterId);

}
