// 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.List;


import com.cloud.host.Host;
import com.cloud.host.HostVO;
import com.cloud.info.ConsoleProxyInfo;
import com.cloud.vm.VMInstanceVO;

/**
 * This class is intended to replace the use of console proxy VMs managed by the Apache CloudStack (ACS)
 * to non ACS console proxy services. The documentation that describe its use and requirements can be found in <a href="https://cwiki.apache.org/confluence/display/CLOUDSTACK/QuickCloud">QuickCloud</a>.
 */
public class AgentBasedStandaloneConsoleProxyManager extends AgentBasedConsoleProxyManager {

    @Override
    public ConsoleProxyInfo assignProxy(long dataCenterId, VMInstanceVO userVm) {

        HostVO host = findHost(userVm);
        if (host != null) {
            HostVO allocatedHost = null;
            /*Is there a consoleproxy agent running on the same machine?*/
            List<HostVO> hosts = _hostDao.listAllIncludingRemoved();
            for (HostVO hv : hosts) {
                if (hv.getType() == Host.Type.ConsoleProxy && hv.getPublicIpAddress().equalsIgnoreCase(host.getPublicIpAddress())) {
                    allocatedHost = hv;
                    break;
                }
            }
            if (allocatedHost == null) {
                /*Is there a consoleproxy agent running in the same pod?*/
                for (HostVO hv : hosts) {
                    if (hv.getType() == Host.Type.ConsoleProxy && hv.getPodId().equals(host.getPodId())) {
                        allocatedHost = hv;
                        break;
                    }
                }
            }
            if (allocatedHost == null) {
                if (logger.isDebugEnabled()) {
                    logger.debug("Failed to find a console proxy at host: {} and in the pod: {} to user vm {}",
                            host::toString, () -> podDao.findById(host.getPodId()), userVm::toString);
                }
                return null;
            }
            if (logger.isDebugEnabled()) {
                logger.debug("Assign standalone console proxy running at {} to user vm {} with public IP {}", allocatedHost, userVm, allocatedHost.getPublicIpAddress());
            }

            // only private IP, public IP, host id have meaningful values, rest of all are place-holder values
            String publicIp = allocatedHost.getPublicIpAddress();
            if (publicIp == null) {
                if (logger.isDebugEnabled()) {
                    logger.debug("Host {} (private IP address: {}) does not have public " +
                            "interface, we will return its private IP for console proxy.",
                            allocatedHost, allocatedHost.getPrivateIpAddress());
                }
                publicIp = allocatedHost.getPrivateIpAddress();
            }

            int urlPort = _consoleProxyUrlPort;
            if (allocatedHost.getProxyPort() != null && allocatedHost.getProxyPort().intValue() > 0) {
                urlPort = allocatedHost.getProxyPort().intValue();
            }

            return new ConsoleProxyInfo(_sslEnabled, publicIp, _consoleProxyPort, urlPort, _consoleProxyUrlDomain);
        } else {
            logger.warn("Host that VM is running is no longer available, console access to VM {} will be temporarily unavailable.", userVm);
        }
        return null;
    }
}
