#!/usr/bin/env python3

# Copyright 2019 The Kapitan Authors
# SPDX-FileCopyrightText: 2020 The Kapitan Authors <kapitan-admins@googlegroups.com>
#
# SPDX-License-Identifier: Apache-2.0

"external input tests"
import os
import sys
import tempfile
import unittest
import string
import random
import stat
import subprocess

import yaml
from kapitan.cached import reset_cache
from kapitan.cli import main
from kapitan.inputs.external import External


class ExternalInputTest(unittest.TestCase):
    def setUp(self):
        os.chdir(os.path.join("tests", "test_resources"))

    def test_compile(self):
        temp = tempfile.mkdtemp()
        sys.argv = ["kapitan", "compile", "--output-path", temp, "-t", "external-test"]
        main()
        self.assertTrue(
            os.path.isfile(
                os.path.join(
                    temp,
                    "compiled",
                    "external-test",
                    "test.md",
                )
            )
        )

    def test_compile_file(self):
        # tests setting of args, env_vars and "\${compiled_target_dir}" being properly substituted
        external_script_content = """
        #!/usr/bin/env bash
        set -ex

        name=$1
        compiled_target_dir=$2

        echo "test-${NAME}" > "${compiled_target_dir}/${name}"
        """
        compile_path = tempfile.mkdtemp()
        temp_dir = tempfile.mkdtemp()
        external_script_file_path = os.path.join(temp_dir, "script.sh")
        with open(external_script_file_path, "w") as f:
            f.write(external_script_content)

        search_paths = [external_script_file_path]
        ref_controller = None

        external_compiler = External(compile_path, search_paths, ref_controller)

        letters = string.ascii_lowercase
        name = "".join(random.choice(letters) for i in range(8))
        external_compiler.set_args([name, "\${compiled_target_dir}"])
        external_compiler.set_env_vars({"NAME": name})

        with self.assertRaises(ValueError) as e:
            external_compiler.compile_file(external_script_file_path, compile_path, None)

        self.assertTrue("Executing external input with command" in e.exception.args[0])
        self.assertTrue("failed" in e.exception.args[0])
        self.assertTrue("Permission denied" in e.exception.args[0])

        # make file executable so there's no failure
        subprocess.check_call(["chmod", "+x", external_script_file_path])
        external_compiler.compile_file(external_script_file_path, compile_path, None)

        generated_file = os.path.join(compile_path, name)
        with open(generated_file, "r") as f:
            generated_file_content = f.readlines()[0]
        self.assertTrue(
            os.path.isfile(generated_file),
            msg="File {} should be generated by compile_file".format(generated_file),
        )
        self.assertEqual(
            generated_file_content, "test-{}\n".format(name), msg="Correct content should be written to file"
        )

    def tearDown(self):
        os.chdir("../../")
        reset_cache()
