"""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_for_add(self):
        """
        Test that we must pass in the repos when adding a subproject, but not
        for other combinations of arguments.
        """
        with self.assertRaises(subprocess.CalledProcessError) as context:
            self.run_with_output(
                self.llvm_projects("--add", "clang"))

        self.assertRegex(
            str(context.exception.output),
            "(.*\n)*.*When adding a subproject you must also pass the --repos argument(.*\n)*")

        # These should not raise.
        self.run_with_output(self.llvm_projects())
        self.run_with_output(
            self.llvm_projects("--remove", "clang"))

    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(
                    "--repos", self.repos,
                    "--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(
            "--repos", self.repos,
            "--add", "clang"))
        self.assertRegex(output, "Projects linked:.*\n.*clang.*")

        output = self.run_with_output(
            self.llvm_projects(
                "--repos", self.repos,
                "--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(
                    "--repos", self.repos,
                    "--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(
                "--repos", self.repos,
                "--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(
            "--repos", self.repos,
            "--add", "clang"))
        self.assertRegex(output,
                         "Projects linked:.*\n" +
                         ".*clang.*")

        output = self.run_with_output(
            self.llvm_projects(
                "--repos", self.repos,
                "--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(
                    "--repos",
                    self.repos,
                    "--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(
                    "--repos",
                    self.repos,
                    "--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(
                "--repos",
                self.repos,
                "--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(
                "--repos",
                self.repos,
                "--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(
                "--repos",
                self.repos,
                "--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(
                "--repos", self.repos,
                "--add", "clang", "lld"))
        self.assertRegex(output, "Projects linked:.*\n.*clang.*\n.*lld.*\n")

        output = self.run_with_output(
            self.llvm_projects(
                "--repos",
                self.repos,
                "--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)
