# Ubuntu-it's website
# Copyright (C) 2015 Pietro Albini
#
# This program is free software: you can redistribute it and/or modify it under
# the terms of the GNU Affero General Public License as published by the Free
# Software Foundation, either version 3 of the License, or (at your option) any
# later version.
#
# This program is distributed in the hope that it will be useful, but WITHOUT
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
# FOR A PARTICULAR PURPOSE.  See the GNU Affero General Public License for more
# details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program.  If not, see <http://www.gnu.org/licenses/>.

import os
import shutil
import glob
import re

import invoke


BASE = os.path.dirname(__file__)
PYTHON = "python3"
PROJECT = "uitwww"


# This is because invoke can't keep backward compatibility...
_invoke_v = invoke.__version__.split(".")
if int(_invoke_v[0]) == 0 and int(_invoke_v[1]) <= 12:
    invoke.task = invoke.ctask


def create_env(name, requirements=False, self=False, force=False):
    """Create a new virtual environment"""
    path = os.path.join(BASE, "build", "envs", name)

    # Don't re-create the environment if force is False
    if os.path.exists(path):
        if force:
            shutil.rmtree(path)
        else:
            return path

    invoke.run("virtualenv -p %s %s" % (PYTHON, path))
    if requirements:
        invoke.run("%s/bin/pip install -r requirements-%s.txt" % (path, name))
    if self:
        invoke.run("%s/bin/pip install -e ." % path)

    return path


@invoke.task
def clean(ctx):
    """Clean all the build things"""
    for dir in "build", "%s.egg-info" % PROJECT:
        path = os.path.join(BASE, dir)
        if not os.path.exists(path):
            continue
        shutil.rmtree(path)

    exclude = ["%s/.git" % BASE, "%s/build" % BASE]
    remove_files = [
        re.compile(r'.py[co]$'), re.compile(r'.mo$'),
        "%s/uitwww/static/website.css" % BASE,
    ]
    remove_dirs = [
        re.compile('__pycache__'),
    ]

    # Remove all the unwanted things
    for root, dirs, files in os.walk(BASE, topdown=False):
        # Skip excluded directories
        skip = False
        for one in exclude:
            if one == root or (root != BASE and one.startswith(root)):
                skip = True
                break
        if skip:
            continue

        # Remove all the unwanted files
        for file in files:
            file = os.path.join(root, file)
            for regex in remove_files:
                if type(regex) == str:
                    if file != regex:
                        continue
                elif not regex.search(file):
                    continue

                os.remove(file)

        # Remove all the unwanted directories
        for dir in dirs:
            dir = os.path.join(root, dir)
            for regex in remove_dirs:
                if type(regex) == str:
                    if dir != regex:
                        continue
                elif not regex.search(dir):
                    continue

                shutil.rmtree(dir)


@invoke.task
def assets(ctx):
    """Build the assets"""
    env = create_env("assets", requirements=True)
    invoke.run(
        "%s/bin/python -mscss < %s/assets/scss/www.scss > %s/uitwww/static/website.css"
        % (env, BASE, BASE)
    )


@invoke.task(pre=[assets])
def devel(ctx):
    """Setup the development environment"""
    create_env("devel", self=True, force=True)


@invoke.task(pre=[assets])
def build(ctx):
    """Create a new build"""
    env = create_env("build", requirements=True)

    out = os.path.join(BASE, "build", "packages")
    if os.path.exists(out):
        for file in glob.glob(os.path.join(out, "*")):
            os.remove(file)

    for type in "sdist", "bdist_wheel":
        invoke.run("%s/bin/python setup.py %s -d %s" % (env, type, out))
