"""Command line interface tests for llvmprojs.py

Note that although this uses the unittest framework, it does *not* contain unit
tests.

"""

import shutil
import os
import subprocess
import unittest

from tempfile import mkdtemp
from uuid import uuid4

from linaropy.cd import cd
from llvmtestcase import LLVMTestCase


class Testllvmprojs(LLVMTestCase):

    @classmethod
    def llvm_projects(cls, *args, **kwargs):
        return cls.command_with_defaults("projects", *args, **kwargs)

    @classmethod
    def get_subproj_repo(cls, subproj):
        return os.path.join(cls.repos, subproj)

    @classmethod
    def setUpClass(cls):
        """Create the file structure and environment that llvmprojs expects"""
        cls.llvm_root = mkdtemp()
        cls.repos = os.path.join(cls.llvm_root, "repos")

        cls.all_repos = ("llvm", "clang", "compiler-rt", "lld", "lldb",
                         "libcxx", "libcxxabi", "libunwind", "test-suite")

        # Create dummy repos
        for reponame in cls.all_repos:
            cls.create_dummy_repo(cls.get_subproj_repo(reponame))

    @classmethod
    def tearDownClass(cls):
        shutil.rmtree(cls.llvm_root)

    @classmethod
    def setUp(cls):
        cls.env = os.path.join(cls.llvm_root, "env" + str(uuid4()))
        cls.llvm_src = os.path.join(cls.env, "llvm")

        # Create LLVM worktree
        cls.branch = "br" + str(uuid4())
        cls.add_worktree(cls.get_subproj_repo("llvm"), cls.llvm_src,
                         cls.branch)

    @classmethod
    def tearDown(cls):
        # Clean up the directories where we might have added subprojects.
        # This isn't 100% clean, because we don't clean up the repos between
        # tests (so any branches will remain), but it's good enough for the
        # current tests.
        for subprojdir in (os.path.join(cls.llvm_src, "projects"),
                           os.path.join(cls.llvm_src, "tools")):
            if os.path.isdir(subprojdir):
                shutil.rmtree(subprojdir)
                os.makedirs(subprojdir)

        # Run prune on the original repos, to remove any dangling worktrees.
        for reponame in cls.all_repos:
            repopath = cls.get_subproj_repo(reponame)
            with cd(repopath):
                cls.run_quietly(["git", "worktree", "prune"])

    def test_repos_arg_is_compulsory(self):
        """
        Test that we must pass in the repos for various combinations of input
        args.
        """
        with self.assertRaises(subprocess.CalledProcessError) as context:
            self.run_with_output(self.llvm_projects(repos=None))

        self.assertRegex(
            str(context.exception.output),
            "(.*\n)*.*the following arguments are required:(.*)--repos(.*\n)*")

        with self.assertRaises(subprocess.CalledProcessError) as context:
            self.run_with_output(
                self.llvm_projects(
                    "--add", "clang", repos=None))

        self.assertRegex(
            str(context.exception.output),
            "(.*\n)*.*the following arguments are required:(.*)--repos(.*\n)*")

        with self.assertRaises(subprocess.CalledProcessError) as context:
            self.run_with_output(
                self.llvm_projects(
                    "--remove",
                    "clang",
                    repos=None))

        self.assertRegex(
            str(context.exception.output),
            "(.*\n)*.*the following arguments are required:(.*)--repos(.*\n)*")

    def test_env_arg_is_compulsory(self):
        """
        Test that we must pass in the environment for various combinations of
        input args.
        """
        with self.assertRaises(subprocess.CalledProcessError) as context:
            self.run_with_output(self.llvm_projects(env=None))

        self.assertRegex(
            str(context.exception.output),
            "(.*\n)*.*the following arguments are required:(.*)--env(.*\n)*")

        with self.assertRaises(subprocess.CalledProcessError) as context:
            self.run_with_output(
                self.llvm_projects(
                    "--add", "clang", env=None))

        self.assertRegex(
            str(context.exception.output),
            "(.*\n)*.*the following arguments are required:(.*)--env(.*\n)*")

        with self.assertRaises(subprocess.CalledProcessError) as context:
            self.run_with_output(
                self.llvm_projects(
                    "--remove", "clang", env=None))

        self.assertRegex(
            str(context.exception.output),
            "(.*\n)*.*the following arguments are required:(.*)--env(.*\n)*")

    def test_dump_empty_config(self):
        """
        Test that we're correctly dumping an empty configuration (i.e. no
        projects linked) when running llvmprojs without arguments.
        """
        output = self.run_with_output(self.llvm_projects())
        self.assertRegex(output, "Projects linked:.*\n.*none.*")

    def test_add_remove_subprojects(self):
        """
        Test that we can add and remove one or several subprojects.
        """
        output = self.run_with_output(self.llvm_projects("--add", "clang"))
        self.assertRegex(output, "Projects linked:.*\n.*clang.*")

        output = self.run_with_output(
            self.llvm_projects(
                "--add", "libcxx", "lldb"))
        self.assertRegex(
            output,
            "Projects linked:.*\n" +
            ".*clang.*\n" +
            ".*libcxx.*\n" +
            ".*lldb.*")

        output = self.run_with_output(self.llvm_projects("--remove", "libcxx"))
        self.assertRegex(output,
                         "Projects linked:.*\n" +
                         ".*clang.*\n" +
                         ".*lldb.*")

        output = self.run_with_output(
            self.llvm_projects(
                "--remove", "clang", "lldb"))
        self.assertRegex(output,
                         "Projects linked:.*\n" +
                         ".*none.*")

    def test_add_remove_invalid_subprojects(self):
        """
        Test that we error out nicely when trying to add/remove invalid
        subprojects.
        """
        with self.assertRaises(subprocess.CalledProcessError) as context:
            self.run_with_output(
                self.llvm_projects(
                    "--add", "inventedsubproject"))

        self.assertRegex(
            str(context.exception.output),
            "(.*\n)*.*invalid choice:.*inventedsubproject(.*\n)*")

        with self.assertRaises(subprocess.CalledProcessError) as context:
            self.run_with_output(
                self.llvm_projects(
                    "--remove",
                    "inventedsubproject"))

        self.assertRegex(
            str(context.exception.output),
            "(.*\n)*.*invalid choice:.*inventedsubproject(.*\n)*")

    def test_duplicate_add_remove(self):
        """
        Test that we don't crash when trying to add / remove the same subproject
        twice with the same command.
        """
        output = self.run_with_output(
            self.llvm_projects(
                "--add", "clang", "lld", "clang"))
        self.assertRegex(output,
                         "Projects linked:.*\n" +
                         ".*clang.*\n" +
                         ".*lld.*")

        output = self.run_with_output(
            self.llvm_projects(
                "--remove", "lld", "lld", "clang"))
        self.assertRegex(output,
                         "Projects linked:.*\n" +
                         ".*none.*")

    def test_redundant_add_remove(self):
        """
        Test that we can add a subproject that already exists (either because it
        was added by our script or manually) or remove a subproject that doesn't
        exist.
        """
        self.add_worktree(self.get_subproj_repo("clang"),
                          os.path.join(self.llvm_src, "tools", "clang"),
                          self.branch)
        self.add_worktree(
            self.get_subproj_repo("compiler-rt"),
            os.path.join(self.llvm_src, "projects", "compiler-rt"),
            self.branch)

        output = self.run_with_output(self.llvm_projects("--add", "clang"))
        self.assertRegex(output,
                         "Projects linked:.*\n" +
                         ".*clang.*")

        output = self.run_with_output(
            self.llvm_projects(
                "--add", "compiler-rt", "lld"))
        self.assertRegex(
            output,
            "Projects linked:.*\n" +
            ".*clang.*\n" +
            ".*compiler-rt.*\n" +
            ".*lld.*")

        output = self.run_with_output(
            self.llvm_projects(
                "--remove", "lldb", "libcxx", "lld"))
        self.assertRegex(
            output,
            "Projects linked:.*\n" +
            ".*clang.*\n" +
            ".*compiler-rt.*")

    def test_simultaneous_add_remove(self):
        """
        Test that we error out when someone is trying to add and remove the same
        project with the same command.
        """
        # Try the really basic case and make sure we're not touching anything
        with self.assertRaises(subprocess.CalledProcessError) as context:
            self.run_with_output(
                self.llvm_projects(
                    "--add",
                    "clang",
                    "--remove",
                    "clang"))

        self.assertRegex(
            str(context.exception.output),
            "(.*\n)*.*Can't add and remove clang at the same time(.*\n)*")

        self.assertFalse(
            os.path.exists(
                os.path.join(self.llvm_src, "tools", "clang")))

        # Try something a bit more complicated and make sure we're not touching
        # anything
        self.add_worktree(
            self.get_subproj_repo("lld"),
            os.path.join(self.llvm_src, "tools", "lld"),
            self.branch)

        with self.assertRaises(subprocess.CalledProcessError) as context:
            self.run_with_output(
                self.llvm_projects(
                    "--add",
                    "clang",
                    "lld",
                    "libcxx",
                    "--remove",
                    "lld",
                    "libcxx"))
        self.assertRegex(
            str(context.exception.output),
            "(.*\n)*" +
            ".*Can't add and remove (lld|libcxx) at the same time(.*\n)*")

        # Make sure we didn't touch anything
        self.assertFalse(
            os.path.exists(
                os.path.join(self.llvm_src, "tools", "clang")))
        self.assertTrue(
            os.path.exists(
                os.path.join(self.llvm_src, "tools", "lld")))
        self.assertFalse(
            os.path.exists(
                os.path.join(self.llvm_src, "projects", "libcxx")))

    def test_multiple_adds_removes(self):
        """
        Test that we can have multiple --add and --remove options in the same
        command and that only the last one of each kind matters.
        """
        output = self.run_with_output(
            self.llvm_projects(
                "--add",
                "libcxxabi",
                "--remove",
                "lld",
                "lldb",
                "--add",
                "clang",
                "libcxx",
                "--remove",
                "libunwind"))
        self.assertRegex(output,
                         "Projects linked:.*\n" +
                         ".*clang.*\n" +
                         ".*libcxx.*\n")

        output = self.run_with_output(
            self.llvm_projects(
                "--add",
                "libunwind",
                "libcxxabi",
                "--remove",
                "clang",
                "libcxx",
                "--add",
                "compiler-rt",
                "--remove",
                "libcxxabi"))
        self.assertRegex(output,
                         "Projects linked:.*\n" +
                         ".*clang.*\n" +
                         ".*compiler-rt.*\n" +
                         ".*libcxx.*\n")

        output = self.run_with_output(
            self.llvm_projects(
                "--add",
                "libcxx",
                "--remove",
                "lld",
                "--add",
                "lld",
                "--remove",
                "libcxx"))
        self.assertRegex(output,
                         "Projects linked:.*\n" +
                         ".*clang.*\n" +
                         ".*compiler-rt.*\n" +
                         ".*lld.*\n")

    def test_different_env(self):
        """
        Test that we can have different environments in completely different
        paths and they don't interfere when we try to add/remove projects.
        """
        # Create a separate environment
        new_env = mkdtemp()
        new_branch = "br" + str(uuid4())
        self.add_worktree(self.get_subproj_repo("llvm"),
                          os.path.join(new_env, "llvm"), new_branch)

        # Check that we start with a clean slate in both the new environment and
        # the one that's already set up
        output = self.run_with_output(self.llvm_projects())
        self.assertRegex(output, "Projects linked:.*\n.*none.*")

        output = self.run_with_output(self.llvm_projects(env=new_env))
        self.assertRegex(output, "Projects linked:.*\n.*none.*")

        # Make sure that adding projects works
        output = self.run_with_output(
            self.llvm_projects(
                "--add", "clang", "lld"))
        self.assertRegex(output, "Projects linked:.*\n.*clang.*\n.*lld.*\n")

        output = self.run_with_output(
            self.llvm_projects(
                "--add",
                "libcxx",
                "libcxxabi",
                env=new_env))
        self.assertRegex(output,
                         "Projects linked:.*\n.*libcxx.*\n.*libcxxabi.*\n.*")

        output = self.run_with_output(self.llvm_projects())
        self.assertRegex(output, "Projects linked:.*\n.*clang.*\n.*lld.*\n")

        # Make sure that removing projects works
        output = self.run_with_output(self.llvm_projects("--remove", "lld"))
        self.assertRegex(output, "Projects linked:.*\n.*clang.*\n")

        output = self.run_with_output(self.llvm_projects("--remove", "libcxx",
                                                         env=new_env))
        self.assertRegex(output,
                         "Projects linked:.*\n.*libcxxabi.*\n.*")

        output = self.run_with_output(self.llvm_projects())
        self.assertRegex(output, "Projects linked:.*\n.*clang.*\n")

        shutil.rmtree(new_env)
