#!/usr/bin/env python
# -*- coding: utf-8 -*-
from __future__ import print_function
import os
import sys
import subprocess
from argparse import ArgumentParser
from os import path as osp


DEFAULT_PY_VERSION = '3'
VENV_TITLE = 'damnode'
VENV_BASENAME = 'venv'
INDEX_URL = None
EXTRA_INDEX_URL = None
PIP_VERSION = '>=9.0.1'
SETUPTOOLS_VERSION = '>=36.0.1'


class VenvCreator(object):
    def __init__(self, py_version):
        if py_version == DEFAULT_PY_VERSION:
            self.venv_dir = VENV_BASENAME
            self.prompt = '({}) '.format(VENV_TITLE)
        else:
            self.venv_dir = '{}-py{}'.format(VENV_BASENAME, py_version)
            self.prompt = '({}-py{}) '.format(VENV_TITLE, py_version)

    def create(self):
        raise NotImplementedError


class Py2VenvCreator(VenvCreator):
    def create(self):
        run(['virtualenv', '--prompt', self.prompt, self.venv_dir])


class Py3VenvCreator(VenvCreator):
    def create(self):
        # TODO: set prompt if python>=3.6
        run(['python3', '-m', 'venv', self.venv_dir])


def main():
    parser = ArgumentParser()
    venv_creator_dict = {
        '2': Py2VenvCreator('2'),
        '3': Py3VenvCreator('3')
    }
    parser.add_argument('-p', '--python',
                        choices=sorted(venv_creator_dict.keys()),
                        default=DEFAULT_PY_VERSION,
                        help='Python version of the virtual env to create (default: {})'.format(
                            DEFAULT_PY_VERSION))
    parser.add_argument('-U', '--upgrade',
                        action='store_true',
                        help='Upgrade packages')
    parser.add_argument('--dev',
                        action='store_true',
                        help='Install requirements-dev.txt')
    args = parser.parse_args()

    base_dir = osp.dirname(osp.abspath(__file__))
    os.chdir(base_dir)

    base_prefix = getattr(sys, 'real_prefix', None) or getattr(sys, 'base_prefix', sys.prefix)
    new_venv_dir = None
    pip = 'pip'

    if base_prefix == sys.prefix:
        info('Not inside virtual env')
        venv_creator = venv_creator_dict[args.python]
        venv_creator.create()
        new_venv_dir = venv_creator.venv_dir
        pip = osp.join(new_venv_dir, 'bin', 'pip')
    else:
        info('Inside virtual env {!r}'.format(sys.prefix))
        sys_py_version = str(sys.version_info[0])

        if sys_py_version != args.python:
            raise RuntimeError('Virtual env Python version {!r} does not match requested version {!r}'.format(
                sys_py_version, args.python))

    pip_install = [pip, 'install']

    if args.upgrade:
        pip_install.append('-U')

    if INDEX_URL:
        pip_install += ['-i', INDEX_URL]

    if EXTRA_INDEX_URL:
        pip_install += ['--extra-index-url', EXTRA_INDEX_URL]

    run(pip_install + ['pip{}'.format(PIP_VERSION)])
    run(pip_install + ['setuptools{}'.format(SETUPTOOLS_VERSION)])
    run(pip_install + ['-e', '.'])

    if args.dev:
        run(pip_install + ['-r', 'requirements-dev.txt'])

    if new_venv_dir:
        info("\nRun 'source {}' to activate virtual env".format(
            osp.join(new_venv_dir, 'bin', 'activate')))


def run(cmd):
    cmdline = subprocess.list2cmdline(cmd)
    info(cmdline)
    subprocess.check_call(cmd)


def info(msg):
    print(msg)
    sys.stdout.flush()


if __name__ == '__main__':
    main()
