# vim: tabstop=4 shiftwidth=4 softtabstop=4

# Copyright 2010 United States Government as represented by the
# Administrator of the National Aeronautics and Space Administration.
# All Rights Reserved.
#
# Copyright 2010 OpenStack, LLC
#
#    Licensed 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.

"""Installation script for Tempest's development virtualenv."""

import optparse
import os
import subprocess
import sys


ROOT = os.path.dirname(os.path.dirname(os.path.realpath(__file__)))
VENV = os.path.join(ROOT, '.venv')
PIP_REQUIRES = os.path.join(ROOT, 'tools', 'pip-requires')
TEST_REQUIRES = os.path.join(ROOT, 'tools', 'test-requires')
PY_VERSION = "python%s.%s" % (sys.version_info[0], sys.version_info[1])


def die(message, *args):
    print >> sys.stderr, message % args
    sys.exit(1)


def check_python_version():
    if sys.version_info < (2, 6):
        die("Need Python Version >= 2.6")


def run_command_with_code(cmd, redirect_output=True, check_exit_code=True):
    """Runs a command in an out-of-process shell.

    Returns the output of that command.  Working directory is ROOT.
    """
    if redirect_output:
        stdout = subprocess.PIPE
    else:
        stdout = None

    proc = subprocess.Popen(cmd, cwd=ROOT, stdout=stdout)
    output = proc.communicate()[0]
    if check_exit_code and proc.returncode != 0:
        die('Command "%s" failed.\n%s', ' '.join(cmd), output)
    return (output, proc.returncode)


def run_command(cmd, redirect_output=True, check_exit_code=True):
    return run_command_with_code(cmd, redirect_output, check_exit_code)[0]


class Distro(object):

    def check_cmd(self, cmd):
        return bool(run_command(['which', cmd], check_exit_code=False).strip())

    def install_virtualenv(self):
        if self.check_cmd('virtualenv'):
            return

        if self.check_cmd('easy_install'):
            print 'Installing virtualenv via easy_install...',
            if run_command(['easy_install', 'virtualenv']):
                print 'Succeeded'
                return
            else:
                print 'Failed'

        die('ERROR: virtualenv not found.\n\nTempest development'
            ' requires virtualenv, please install it using your'
            ' favorite package management tool')

    def post_process(self):
        """Any distribution-specific post-processing gets done here.

        In particular, this is useful for applying patches to code inside
        the venv.
        """
        pass


class Fedora(Distro):
    """This covers Fedora-based distributions.

    Includes: Fedora, RHEL, Scientific Linux"""

    def check_pkg(self, pkg):
        return run_command_with_code(['rpm', '-q', pkg],
                                     check_exit_code=False)[1] == 0

    def yum_install(self, pkg, **kwargs):
        print "Attempting to install '%s' via yum" % pkg
        run_command(['sudo', 'yum', 'install', '-y', pkg], **kwargs)

    def apply_patch(self, originalfile, patchfile):
        run_command(['patch', originalfile, patchfile])

    def install_virtualenv(self):
        if self.check_cmd('virtualenv'):
            return

        if not self.check_pkg('python-virtualenv'):
            self.yum_install('python-virtualenv', check_exit_code=False)

        super(Fedora, self).install_virtualenv()

    def post_process(self):
        """Workaround for a bug in eventlet.

        This currently affects RHEL6.1, but the fix can safely be
        applied to all RHEL and Fedora distributions.

        This can be removed when the fix is applied upstream.

        Nova: https://bugs.launchpad.net/nova/+bug/884915
        Upstream: https://bitbucket.org/which_linden/eventlet/issue/89
        """

        # Install "patch" program if it's not there
        if not self.check_pkg('patch'):
            self.yum_install('patch')

        # Apply the eventlet patch
        self.apply_patch(os.path.join(VENV, 'lib', PY_VERSION, 'site-packages',
                                      'eventlet/green/subprocess.py'),
                         'contrib/redhat-eventlet.patch')


class CentOS(Fedora):
    """This covers CentOS."""

    def post_process(self):
        if not self.check_pkg('openssl-devel'):
            self.yum.install('openssl-devel', check_exit_code=False)


def get_distro():
    if (os.path.exists('/etc/fedora-release') or
            os.path.exists('/etc/redhat-release')):
        if os.path.exists('/etc/redhat-release') \
            and run_command_with_code(['grep', 'CentOS',
                                       '/etc/redhat-release']) == 0:
            return CentOS()
        else:
            return Fedora()
    else:
        return Distro()


def check_dependencies():
    get_distro().install_virtualenv()


def create_virtualenv(venv=VENV, no_site_packages=True):
    """Creates the virtual environment and installs PIP.

    Creates the virtual environment and installs PIP only into the
    virtual environment.
    """
    print 'Creating venv...',
    if no_site_packages:
        run_command(['virtualenv', '-q', '--no-site-packages', VENV])
    else:
        run_command(['virtualenv', '-q', VENV])
    print 'done.'
    print 'Installing pip in virtualenv...',
    if not run_command(['tools/with_venv.sh', 'easy_install',
                        'pip>1.0']).strip():
        die("Failed to install pip.")
    print 'done.'


def pip_install(*args):
    run_command(['tools/with_venv.sh',
                 'pip', 'install', '--upgrade'] + list(args),
                redirect_output=False)


def install_dependencies(venv=VENV):
    print 'Installing dependencies with pip (this can take a while)...'

    # First things first, make sure our venv has the latest pip and distribute.
    # NOTE: we keep pip at version 1.1 since the most recent version causes
    # the .venv creation to fail. See:
    # https://bugs.launchpad.net/nova/+bug/1047120
    pip_install('pip==1.1')
    pip_install('distribute')

    # Install greenlet by hand - just listing it in the requires file does not
    # get it in stalled in the right order
    pip_install('greenlet')

    pip_install('-r', PIP_REQUIRES)
    pip_install('-r', TEST_REQUIRES)

    # Install tempest into the virtual_env. No more path munging!
    run_command([os.path.join(venv, 'bin/python'), 'setup.py', 'develop'])


def post_process():
    get_distro().post_process()


def print_help():
    help = """
    Tempest development environment setup is complete.

    Tempest development uses virtualenv to track and manage Python dependencies
    while in development and testing.

    To activate the Tempest virtualenv for the extent of your current shell
    session you can run:

    $ source .venv/bin/activate

    Or, if you prefer, you can run commands in the virtualenv on a case by case
    basis by running:

    $ tools/with_venv.sh <your command>

    Also, make test will automatically use the virtualenv.
    """
    print help


def parse_args():
    """Parses command-line arguments."""
    parser = optparse.OptionParser()
    parser.add_option("-n", "--no-site-packages", dest="no_site_packages",
                      default=False, action="store_true",
                      help="Do not inherit packages from global Python"
                           " install")
    return parser.parse_args()


def main(argv):
    (options, args) = parse_args()
    check_python_version()
    check_dependencies()
    create_virtualenv(no_site_packages=options.no_site_packages)
    install_dependencies()
    post_process()
    print_help()

if __name__ == '__main__':
    main(sys.argv)
