#!/usr/bin/env python
# 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.

"""examines environment, then:
	- configures classpath as per environment or command-line options
	- detects Tomcat (on Windows)
	- detects or configures directories according to command-line options"""

import Utils,Node,Options,Logs,Scripting,Environment,Build,Configure
from os import unlink as _unlink, makedirs as _makedirs, getcwd as _getcwd, chdir as _chdir
try: from os import getuid as _getuid
except ImportError: pass
from os.path import abspath as _abspath, basename as _basename, dirname as _dirname, exists as _exists, isdir as _isdir, split as _split, join as _join, expanduser as _expanduser, sep, pathsep, pardir
from glob import glob as _glob
import time


# list of JARs that provide the build dependencies
# "j" generally means /usr/share/java
# when adding a new system JAR file:
# 1. check the hard_deps variable at the bottom and add the appropriate packaging information,
# 2. add the RPM package that contains the jarfile into the cloud.spec file, and the DEB package into the debian/control file
# 3. (the jars specified here will be looked up at runtime with build-classpath, on linux installs)
systemjars = {
	'common':
	(
		"commons-collections.jar",
		# "commons-daemon.jar",
		#"commons-dbcp.jar",
		"commons-codec.jar",
		"commons-logging.jar",
		"commons-logging-api.jar",
		#"commons-pool.jar",
		"commons-httpclient.jar",
		"ws-commons-util.jar",
		"mysql-connector-java.jar",
	),
	'Fedora':
	(
		"tomcat6-servlet-2.5-api.jar",
		"tomcat6-el-2.1-api-6.0.26.jar",
		"tomcat6-jsp-2.1-api-6.0.26.jar",
		#"tomcat6/catalina.jar", # all supported distros put the file there
	),
	'RHEL':
	(
		"tomcat6-servlet-2.5-api.jar",
		"tomcat6-el-2.1-api-6.0.24.jar",
		"tomcat6-jsp-2.1-api-6.0.24.jar",
                "jakarta-taglibs-core-1.1.1.jar",
                "jakarta-taglibs-standard-1.1.1.jar",
                "tomcat6/jasper.jar",
                "tomcat6/jasper-el.jar",
                "tomcat6/jasper-jdt.jar",
                
	),
	'CentOS':
	(
		"tomcat6-servlet-2.5-api.jar",
		"tomcat6-jsp-2.1-api-6.0.24.jar",
		"tomcat6-el-2.1-api-6.0.24.jar",
                "jakarta-taglibs-core-1.1.1.jar",
                "jakarta-taglibs-standard-1.1.1.jar",
                "tomcat6/jasper.jar",
                "tomcat6/jasper-el.jar",
                "tomcat6/jasper-jdt.jar",
		#"tomcat6/catalina.jar", # all supported distros put the file there
	),
	'Ubuntu':
	(
		"servlet-api-2.5.jar",
		"jsp-api-2.1.jar",
		"jasper.jar",
		"el-api-2.1.jar",
		"jasper-el.jar",
		"ecj.jar",
		"cglib.jar",
		"asm3.jar",
		"jsch.jar",
		"backport-util-concurrent.jar",
		"jetty.jar",
		"jetty-util.jar",
		"jetty-start-daemon.jar",
		"jetty-sslengine.jar",
		"jetty-start.jar",
		"jna.jar",
		"log4j-1.2.jar",
	),
	'Windows':
	(
		"servlet-api.jar", # this ships with Tomcat in lib/
		#"catalina.jar",
	),
	'Mac':
	(
		"servlet-api.jar",
	),
	'openSUSE':
	(
		"tomcat6-servlet-2.5-api.jar",
		"tomcat6-jsp-2.1-api-6.0.24.jar",
		"tomcat6-el-1.0-api.jar"
	),
	'SLES':
	(
		"tomcat6-servlet-2.5-api.jar",
		"tomcat6-jsp-2.1-api-6.0.24.jar",
		"tomcat6-el-1.0-api.jar"
	)
}

#A JAR dependency may be:

#- required during compile-time
#- required during run-time

#A JAR file can be available:

#- in Tomcat lib/
#- as a Linux system package
#- in the cloud-deps package
#- in the cloud-premium package

# servlet-api:

#- is required during compile-time
#- is required during management server run-time
#- is available in Tomcat lib/ (Windows/Mac) AND as a system package (Linux)
#  -> ERGO, we do not need to include it 
#           but it should be named on the SYSTEMJARS (which is then used in the tomcat6.conf to build the MS classpath),
#           and it should also be in the compile-time CLASSPATH

# =====================================

# list of dependencies for configure check
# (classname,fedora package name,ubuntu package name)
# when adding a package name here, also add to the spec or debian control file
hard_deps = [
	('java.io.FileOutputStream',"java-devel","openjdk-6-jdk"),
	('javax.servlet.http.Cookie',"tomcat6-servlet-2.5-api","libservlet2.5-java","(if on Windows,did you set TOMCAT_HOME to point to your Tomcat setup?)"),
	('org.apache.naming.resources.Constants',"tomcat6-lib","libtomcat6-java","(if on Windows,did you set TOMCAT_HOME to point to your Tomcat setup?)"),
]


if Options.options.VERNUM:
	Version = Options.options.VERNUM
else:
	Version = "2.2"
builddate = time.strftime("%Y.%m.%d.%H.%M.%S", time.localtime()).replace('.','')
conf.env.VERSION = Version + "." + builddate

conf.check_message_1('Detecting distribution')
if Options.platform == 'win32': conf.env.DISTRO = "Windows"
elif Options.platform == 'darwin': conf.env.DISTRO = "Mac"
elif _exists("/etc/network"): conf.env.DISTRO = "Ubuntu"
elif _exists("/etc/fedora-release"): conf.env.DISTRO = "Fedora"
elif _exists("/etc/centos-release"): conf.env.DISTRO = "CentOS"
elif _exists("/etc/redhat-release"):
    version = file("/etc/redhat-release").readline()
    if version.find("Red Hat Enterprise Linux Server release 6") != -1:
        conf.env.DISTRO = "RHEL"
    elif version.find("CentOS release") != -1:
        conf.env.DISTRO = "CentOS"
elif _exists("/etc/SuSE-release"):
    content = file("/etc/SuSE-release").readlines()
    supportedVersion = None
    if content[0].find("SUSE Linux Enterprise Server 11") != -1:
        spLevel = eval(content[-1].split()[-1])
        if spLevel >= 2:
            conf.env.DISTRO = "SLES"
            supportedVersion = 1
    elif content[0].find("openSUSE") != -1:
        version = eval(content[1].split()[-1])
        if version >= 12.1:
            conf.env.DISTRO = "openSUSE"
            supportedVersion = 1
    if not supportedVersion:
        conf.env.DISTRO = "unknown"
else: conf.env.DISTRO = "unknown"
if conf.env.DISTRO == "unknown": c = "YELLOW"
else: 				    c = "GREEN"
conf.check_message_2(conf.env.DISTRO,c)
conf.check_message_1('Detecting installation prefix')
if Options.options.prefix == Options.default_prefix:
	if conf.env.DISTRO == 'Windows':
		conf.env.PREFIX = 'C:\\CloudStack'
	elif _getuid() != 0: # not root
		conf.env.PREFIX = _join(_expanduser("~"),"cloudstack")
conf.check_message_2("%s"%conf.env.PREFIX,"GREEN")

conf.check_tool('misc')

conf.check_tool("gnu_dirs")
if conf.env.DISTRO == 'Windows':
	# waf uses slashes somewhere along the line in some paths.  we fix them on windows.
	for pth in [ x for x in conf.env.get_merged_dict().keys() if x.endswith("DIR") ]:
		if not pth: continue
		if not conf.env[pth]: continue
		conf.env[pth] = conf.env[pth].replace("/","\\")

conf.check_tool('tar')
try: conf.check_tool('mkisofs')
except Configure.ConfigurationError,e:
	raise Configure.ConfigurationError, "The program genisoimage (or mkisofs) could not be found.\nOn Linux: ./waf installrpmdeps or ./waf installdebdeps according to your distro's package format.\nOn Windows: Use cygwin to install the mkisofs package, then ensure that the program is in your PATH."
conf.check_tool('java')

conf.check_tool("python")
conf.check_python_version((2,4,0))

conf.check_message_1('Detecting Python MySQL module')
try: import MySQLdb
except ImportError,e:
	raise Configure.ConfigurationError, "The Python MySQLdb module could not be found.\nOn Linux: ./waf installrpmdeps or ./waf installdebdeps according to your distro's package format.\nOn Windows: Install MySQL 5.1 on your machine, then install the Python MySQLdb module for Python %s.\nThe module for Python 2.6 / win32 / MySQL 5.1 is available here: http://soemin.googlecode.com/files/MySQL-python-1.2.3c1.win32-py2.6.exe"%conf.env.PYTHON_VERSION
conf.check_message_2('MySQLdb','GREEN')
conf.check_message_1('Database info for developer setup')
for a in "DBHOST DBUSER DBPW".split(): conf.env[a] = getattr(Options.options, a, '')
conf.check_message_2("user: %r, password: %r, host: %r"%(conf.env.DBUSER,conf.env.DBPW,conf.env.DBHOST),'GREEN')

try: conf.check_tool("tomcat")
except Configure.ConfigurationError,e:
	conf.fatal("Tomcat directory %r not found.  Either install Tomcat using ./waf installrpmdeps or ./waf installdebdeps, or manually install Tomcat to a directory in your system and set the environment variable TOMCAT_HOME to point to it."%conf.env.TOMCATHOME)

conf.env.COMMONPATH = _join(conf.env.PACKAGE,"common")
conf.env.AGENTPATH = _join(conf.env.PACKAGE,"agent")
conf.env.CPPATH = _join(conf.env.PACKAGE,"console-proxy")
conf.env.IPALLOCATORPATH = _join(conf.env.PACKAGE,"ipallocator")
conf.env.MSPATH = _join(conf.env.PACKAGE,"management")
conf.env.USAGEPATH = _join(conf.env.PACKAGE,"usage")
conf.env.SETUPPATH = _join(conf.env.PACKAGE,"setup")
conf.env.SERVERPATH = _join(conf.env.PACKAGE,"server")

if conf.env.DISTRO in ['Windows','Mac']:
	conf.env.MSENVIRON = conf.env.TOMCATHOME
	conf.env.MSCONF  = _join(conf.env.TOMCATHOME,"conf")
	conf.env.MSLOGDIR = _join(conf.env.TOMCATHOME,"logs")
	conf.env.MSMNTDIR = _join(conf.env.TOMCATHOME,"mnt")
        conf.env.JAVADIR = _join(conf.env.MSENVIRON,"lib")
	conf.env.PREMIUMJAVADIR = conf.env.JAVADIR
	conf.env.PLUGINJAVADIR = conf.env.JAVADIR
	conf.env.SYSTEMJAVADIR = conf.env.JAVADIR
else:
	conf.env.MSENVIRON = _join(conf.env.DATADIR,conf.env.MSPATH)
	conf.env.MSCONF    = _join(conf.env.SYSCONFDIR,conf.env.MSPATH)
	conf.env.MSLOGDIR = _join(conf.env.LOCALSTATEDIR,"log",conf.env.MSPATH)
	conf.env.MSMNTDIR = _join(conf.env.SHAREDSTATEDIR,conf.env.PACKAGE,"mnt")
	conf.check_tool('compiler_cc')
	conf.check_cc(lib='dl')
	conf.check_tool('usermgmt')
	conf.check_message_1('Determining management server user name')
	msuser = getattr(Options.options, 'MSUSER', '')
	if msuser:
		conf.env.MSUSER = msuser
		conf.check_message_2("%s (forced through --tomcat-user)"%conf.env.MSUSER,"GREEN")
	else:
		conf.env.MSUSER = conf.env.PACKAGE
		conf.check_message_2("%s (Linux default)"%conf.env.MSUSER,"GREEN")
	conf.check_tool("javadir")
	conf.env.PREMIUMJAVADIR = _join(conf.env.JAVADIR,"%s-premium"%conf.env.PACKAGE)
	conf.env.PLUGINJAVADIR = _join(conf.env.JAVADIR,"%s-plugins"%conf.env.PACKAGE)
	conf.env.SYSTEMJAVADIR = "/usr/share/java"

in_javadir = lambda name: _join(conf.env.JAVADIR,_basename(name)) # $PREFIX/share/java
in_system_javadir = lambda name: _join(conf.env.SYSTEMJAVADIR,name) # /usr/share/java
in_premiumjavadir = lambda name: _join(conf.env.PREMIUMJAVADIR,name) # $PREFIX/share/java/cloud-premium

conf.env.COMMONLIBDIR = Utils.subst_vars(_join("${LIBDIR}","${COMMONPATH}"),conf.env)

conf.env.AGENTLIBDIR = Utils.subst_vars(_join("${LIBDIR}","${AGENTPATH}"),conf.env)
conf.env.AGENTSYSCONFDIR = Utils.subst_vars(_join("${SYSCONFDIR}","${AGENTPATH}"),conf.env)
conf.env.AGENTLOGDIR = Utils.subst_vars(_join("${LOCALSTATEDIR}","log","${AGENTPATH}"),conf.env)

conf.env.USAGELOGDIR = Utils.subst_vars(_join("${LOCALSTATEDIR}","log","${USAGEPATH}"),conf.env)
conf.env.USAGESYSCONFDIR = Utils.subst_vars(_join("${SYSCONFDIR}","${USAGEPATH}"),conf.env)

conf.env.CPLIBDIR = Utils.subst_vars(_join("${LIBDIR}","${CPPATH}"),conf.env)
conf.env.CPSYSCONFDIR = Utils.subst_vars(_join("${SYSCONFDIR}","${CPPATH}"),conf.env)
conf.env.CPLOGDIR = Utils.subst_vars(_join("${LOCALSTATEDIR}","log","${CPPATH}"),conf.env)

conf.env.MSLOG = _join(conf.env.MSLOGDIR,"management-server.log")
conf.env.AWSAPILOG = _join(conf.env.MSLOGDIR,"awsapi.log")
conf.env.APISERVERLOG = _join(conf.env.MSLOGDIR,"api-server.log")
conf.env.AGENTLOG = _join(conf.env.AGENTLOGDIR,"agent.log")
conf.env.USAGELOG = _join(conf.env.USAGELOGDIR,"usage.log")
conf.env.CPLOG = _join(conf.env.CPLOGDIR,"console-proxy.log")

conf.env.SETUPDATADIR = Utils.subst_vars(_join("${DATADIR}","${SETUPPATH}"),conf.env)

conf.env.SERVERSYSCONFDIR = Utils.subst_vars(_join("${SYSCONFDIR}","${SERVERPATH}"),conf.env)
conf.env.PIDDIR = _join(conf.env.LOCALSTATEDIR,"run")
conf.env.LOCKDIR = _join(conf.env.LOCALSTATEDIR,"lock","subsys")


conf.check_message_1('Building classpaths')

# == Here we build the run-time classpaths ==

# The system classpath points to JARs we expect the user has installed using distro packages
# not used for Windows and Mac (except for servlet-api.jar) because we install them from the thirdparty/ directory
sysjars = list(systemjars['common'])
if conf.env.DISTRO in systemjars.keys(): sysjars = sysjars + list(systemjars[conf.env.DISTRO])
conf.env.SYSTEMJARS = " ".join(sysjars) # used by build-classpath in the initscripts
conf.env.SYSTEMCLASSPATH = pathsep.join([ in_system_javadir(x) for x in sysjars ]) # used for compile, waf run and simulate_agent

# the deps classpath points to JARs that are installed in the cloud-deps package
# these will install on Tomcat6's lib/ directory on Windows and Mac
depsclasspath = [ in_javadir(_basename(x)) for x in _glob(_join(conf.srcdir,"deps","*.jar")) ]
conf.env.DEPSCLASSPATH = pathsep.join(depsclasspath)

# the MS classpath points to JARs required to run the management server
msclasspath = [ in_javadir("%s-%s.jar"%(conf.env.PACKAGE,x)) for x in "utils api core server server-extras core-extras vmware-base ovm dp-user-concentrated-pod dp-user-dispersing host-allocator-random plugin-f5 plugin-netscaler plugin-ovs plugin-srx storage-allocator-random user-authenticator-ldap user-authenticator-md5 user-authenticator-plaintext vmware plugin-hypervisor-xen plugin-nicira-nvp plugin-elb plugin-netapp".split() ]
conf.env.MSCLASSPATH = pathsep.join(msclasspath)

# the agent and simulator classpaths point to JARs required to run these two applications
agentclasspath = [ in_javadir("%s-%s.jar"%(conf.env.PACKAGE,x)) for x in "utils api core server server-extras agent console-common console-proxy core-extras agent-extras plugin-hypervisor-kvm".split() ]
agentclasspath.append(in_javadir("jna.jar"))
conf.env.AGENTCLASSPATH = pathsep.join(agentclasspath)
conf.env.AGENTSIMULATORCLASSPATH = pathsep.join(agentclasspath+[in_javadir("%s-agent-simulator.jar"%conf.env.PACKAGE)])

usageclasspath = [ in_javadir("%s-%s.jar"%(conf.env.PACKAGE,x)) for x in "utils api core server server-extras usage core-extras".split() ]
conf.env.USAGECLASSPATH = pathsep.join(usageclasspath)

# the premium classpath was ELIMINATED
# CloudStack now detects the premium classpath at runtime by iterating through the JAR files in @PREMIUMJAVADIR@
# premium JARs will install on Tomcat6's lib/ directory on Windows and Mac

# The compile path is composed of the
# 1. source directories (without including the JARs)
# JARs are not included because in case of parallel compilation (IOW, all the time), javac picks up half-written JARs and die
compilecp = []# list(srcdirs)
# 2.b) the deps/ directory in the source if on Linux
# 2.a) the thirdparty/ directory if available
if conf.env.DISTRO in ["Windows","Mac"]:
	pass
else:
	compilecp+= _glob(_join("deps","*.jar"))
compilecp+= _glob(_join("cloudstack-proprietary","thirdparty","*.jar"))
# 3. the system classpath (system-installed JARs)
compilecp+= [ conf.env.SYSTEMCLASSPATH ]
compilecp+= _glob(_join(conf.env.TOMCATHOME,'bin',"*.jar"))
compilecp+= _glob(_join(conf.env.TOMCATHOME,'lib',"*.jar"))
conf.env.CLASSPATH = pathsep.join(compilecp)
conf.check_message_2('Done','GREEN')

# log4j config and property config files require backslash escapes on Windows

conf.env.COMMONLIBDIR = Utils.subst_vars(_join("${LIBDIR}","${COMMONPATH}"),conf.env)

conf.env.AGENTLIBDIR = Utils.subst_vars(_join("${LIBDIR}","${AGENTPATH}"),conf.env)
conf.env.AGENTSYSCONFDIR = Utils.subst_vars(_join("${SYSCONFDIR}","${AGENTPATH}"),conf.env)
conf.env.AGENTLOGDIR = Utils.subst_vars(_join("${LOCALSTATEDIR}","log","${AGENTPATH}"),conf.env)

conf.env.USAGELOGDIR = Utils.subst_vars(_join("${LOCALSTATEDIR}","log","${USAGEPATH}"),conf.env)
conf.env.USAGESYSCONFDIR = Utils.subst_vars(_join("${SYSCONFDIR}","${USAGEPATH}"),conf.env)

conf.env.CPLIBDIR = Utils.subst_vars(_join("${LIBDIR}","${CPPATH}"),conf.env)
conf.env.CPSYSCONFDIR = Utils.subst_vars(_join("${SYSCONFDIR}","${CPPATH}"),conf.env)
conf.env.CPLOGDIR = Utils.subst_vars(_join("${LOCALSTATEDIR}","log","${CPPATH}"),conf.env)

conf.env.CLIPATH = _join(conf.env.PACKAGE,"cli")

conf.env.IPALLOCATORLIBDIR = Utils.subst_vars(_join("${LIBDIR}","${IPALLOCATORPATH}"),conf.env)
conf.env.IPALLOCATORSYSCONFDIR = Utils.subst_vars(_join("${SYSCONFDIR}","${IPALLOCATORPATH}"),conf.env)
conf.env.IPALLOCATORLOGDIR = Utils.subst_vars(_join("${LOCALSTATEDIR}","log","${IPALLOCATORPATH}"),conf.env)

conf.env.MSLOG = _join(conf.env.MSLOGDIR,"management-server.log")
conf.env.APISERVERLOG = _join(conf.env.MSLOGDIR,"api-server.log")
conf.env.AGENTLOG = _join(conf.env.AGENTLOGDIR,"agent.log")
conf.env.USAGELOG = _join(conf.env.USAGELOGDIR,"usage.log")
conf.env.CPLOG = _join(conf.env.CPLOGDIR,"console-proxy.log")
conf.env.IPALOCATORLOG = _join(conf.env.IPALLOCATORLOGDIR,"ipallocator.log")

conf.env.SETUPDATADIR = Utils.subst_vars(_join("${DATADIR}","${SETUPPATH}"),conf.env)

conf.env.CLIDIR = Utils.subst_vars(_join("${SYSCONFDIR}","${CLIPATH}"),conf.env)

conf.env.SERVERSYSCONFDIR = Utils.subst_vars(_join("${SYSCONFDIR}","${SERVERPATH}"),conf.env)

if conf.env.DISTRO in ["Windows"]:
	for log in "MSLOG APISERVERLOG AGENTLIBDIR USAGELOG AGENTLOG".split(): conf.env[log] = conf.env[log].replace("\\","\\\\")

no_java_class = lambda x: conf.check_java_class(x,with_classpath=conf.env.CLASSPATH) != 0
def require_dependency(javacls,packagenames):
	if no_java_class(javacls):
		conf.fatal("Cannot find the Java class %s (available in the distro packages: %s)"%(
			javacls, ", ".join(packagenames)))
def check_dependencies(deps):
	for d in deps:
		cls,pkgs = d[0],d[1:]
		require_dependency(cls,pkgs)

if not getattr(Options.options, 'NODEPCHECK', ''): check_dependencies(hard_deps)

Utils.pprint("WHITE","Configure finished.  Use 'python waf showconfig' to show the configure-time environment.")
