// 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().equals(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;
	}
}
