// 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 javax.ejb.Local;

import org.apache.log4j.Logger;
import org.springframework.stereotype.Component;

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

@Local(value={ConsoleProxyManager.class})
public class AgentBasedStandaloneConsoleProxyManager extends
AgentBasedConsoleProxyManager {
	private static final Logger s_logger = Logger.getLogger(AgentBasedStandaloneConsoleProxyManager.class);

	@Override
	public ConsoleProxyInfo assignProxy(long dataCenterId, long userVmId) {
		UserVmVO userVm = _userVmDao.findById(userVmId);
		if (userVm == null) {
			s_logger.warn("User VM " + userVmId
					+ " no longer exists, return a null proxy for user vm:"
					+ userVmId);
			return null;
		}

		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() == host.getPodId()) {
						allocatedHost = hv;
						break;
					}
				}
			}
			if (allocatedHost == null) {
				if(s_logger.isDebugEnabled())
					s_logger.debug("Failed to find a console proxy at host: " + host.getName() + " and in the pod: " + host.getPodId() + " to user vm " + userVmId);
				return null;
			}
			if(s_logger.isDebugEnabled())
				s_logger.debug("Assign standalone console proxy running at " + allocatedHost.getName() + " to user vm " + userVmId + " with public IP " + 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(s_logger.isDebugEnabled())
					s_logger.debug("Host " + allocatedHost.getName() + "/" + allocatedHost.getPrivateIpAddress() +
					" does not have public interface, we will return its private IP for cosole proxy.");
				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 {
			s_logger.warn("Host that VM is running is no longer available, console access to VM " + userVmId + " will be temporarily unavailable.");
		}
		return null;
	}
}
