#!/usr/bin/env python
"""
Creates an apache2 VirtualHost using templates.
"""
import os, sys
import grp, pwd
import webbrowser

def status(txt):
    print("\033[92m [+] \033[0m %s\033[0m" % (txt))
    return True

def err(txt):
    print("\033[91m [!] %s\033[0m" % (txt))
    return False

def install_host(hostname, **kwargs):
    text = create_host(hostname, **kwargs)
    conf = "/etc/apache2/sites-available/%s.conf" % hostname
    if os.path.exists(conf):
        return err("Config file %s already exists!" % conf)

    status("Creating config file at %s" % conf)
    with open(conf, 'w') as fd:
        fd.write(text)
    status("Done")

    path = "/var/www/vhosts/%s/web" % hostname
    if os.path.exists(path):
        return err("Path %s already exists!" % path)

    status("Creating path %s" % path)
    os.makedirs(path, 0775)
    gid = grp.getgrnam('www-data').gr_gid
    uid = pwd.getpwnam('www-data').pw_uid
    os.chown(path, uid, gid)
    code = os.system("a2ensite %s" % hostname)

    if code is 256:
        return err("Can't run a2ensite on '%s'. Check %s and try again." % 
            (hostname, conf))

    code = os.system("service apache2 reload")
    if code is not 0:
        return err("Could not restart apache (returned exit code %s)"%(str(code)))

    status("Done")
    raw_input("Press enter to create hosts entry")
    create_hosts_entry(hostname)
    raw_input("Press enter to reload apache")
    os.system("a2ensite %s" % hostname)
    os.system('service apache2 reload')

    status("Launching http://%s" % hostname)
    webbrowser.open("http://%s" % hostname)
    os.chdir(path)
    sys.exit(0)

def create_hosts_entry(hostname):
    status("Reading /etc/hosts...")
    with open('/etc/hosts', 'r') as hostfile:
        lines = hostfile.readlines()

    entry = "127.0.0.1 %s" % hostname

    status("Adding entry: \033[1m%s\033[0m" % entry)
    lines.insert(0, entry)

    status("Writing new hosts file...")
    with open('/etc/hosts', 'w') as hostfile2:
        hostfile2.write(os.linesep.join(lines))

    return status("Done")

def create_host(hostname, **kwargs):
    """Accepts a hostname (foo.local) and kwargs.
    """
    ip = kwargs.get('ip', '*')
    port = kwargs.get('port', '80')

    ServerName = kwargs.get('ServerName', hostname)
    ServerAlias = kwargs.get('ServerAlias', None)
    ServerAdmin = kwargs.get('ServerAdmin', "webmaster@%s" % hostname)
    DocumentRoot = kwargs.get('DocumentRoot', "/var/www/vhosts/%s/web" % hostname)

    ErrorLog = kwargs.get('ErrorLog', '${APACHE_LOG_DIR}/error.log')
    CustomLog = kwargs.get('CustomLog', '${APACHE_LOG_DIR}/access.log combined')

    indexes = '-'

    lines = []
    lines.append("## Generated by virtualhost script")
    lines.append("<VirtualHost %s:%s>" % (ip, port))
    lines.append("    ServerName %s" % (ServerName))
    if ServerAlias:
        if type(ServerAlias) is list:
            for alias in ServerAlias:
                lines.append("    ServerAlias %s" % alias)
        elif type(ServerAlias) is str:
            lines.append("    ServerAlias %s" % ServerAlias)
    lines.append("    ServerAdmin %s" % ServerAdmin)
    lines.append("    DocumentRoot %s" % DocumentRoot)
    lines.append("")
    lines.append("    <Directory %s>" % DocumentRoot)
    lines.append("        Options %sIndexes" % (indexes))
    lines.append("        Order allow,deny")
    lines.append("        Allow from all")
    lines.append("    </Directory>")
    lines.append("")
    lines.append("    ErrorLog %s" % ErrorLog)
    lines.append("    CustomLog %s" % CustomLog)
    lines.append("</VirtualHost>")
    
    text = os.linesep.join(lines)
    return text

def create_host_ssl(hostname, **kwargs):
    lines = []
    lines.append("    SSLEngine On")
    lines.append("    SSLCertificateFile %s" % pemfile)
    lines.append("    SSLCertificateKeyFile %s" % keyfile)
    lines.append("    SSLCertificateChainFile %s" % chainfile)
    lines.append("    SSLCACertificatePath %s" % cacertpath)
    lines.append("    SSLCACertificateFile %s" % cacertfile)
    lines.append("    SSLCARevocationPath %s" % revocationpath)
    lines.append("    SSLCARevocationFile %s" % revocationfile)
    ## none, optional, require optional_no_ca
    lines.append("    SSLVerifyClient %s" % verifyclient)
    lines.append("    SSLVerifyDepth %s" % verifydepth)
    lines.append("    <FilesMatch \"\\.(cgi|shtml|phtml|php)$\">")
    lines.append("        SSLOptions +StdEnvVars")
    lines.append("    </FilesMatch>")
    lines.append("    BrowserMatch \"MSIE [2-6]\" \\ ")
    lines.append("        nokeepalive ssl-unclean-shutdown \\")
    lines.append("        downgrade-1.0 force-response-1.0")
    lines.append("    BrowserMatch \"MSIE [17-9]\" ssl-unclean-shutdown")

if __name__ == "__main__":
    try:
        hostname = sys.argv[1]
        install_host(hostname)
        sys.exit(0)
    except IndexError:
        err("Usage: %s <hostname>" % sys.argv[0])
        sys.exit(1)
