# -*-coding: utf-8 -*-

"""Testing script for cvelib/patchapplier.py."""

import unittest
from unittest import mock
import tempfile
import subprocess
import os

from cvelib import patchapplier as pa
from cvelib import common


def get_sha(kernel_path):
    """Returns most recent commit sha."""
    try:
        sha = subprocess.check_output(['git', 'log', '-1', '--format=%H'],
                                      stderr=subprocess.DEVNULL, cwd=kernel_path,
                                      encoding='utf-8')
    except subprocess.CalledProcessError:
        raise Exception('Sha was not found')

    return sha.rstrip('\n')


class TestPatchApplier(unittest.TestCase):
    """Test class for cvelib/patchapplier.py."""

    def setUp(self):
        # Backup $LINUX and $CHROMIUMOS_KERNEL.
        self.linux = os.getenv('LINUX')
        self.cros_kernel = os.getenv('CHROMIUMOS_KERNEL')

        # Make temporary directory for $LINUX.
        self.linux_temp = tempfile.mkdtemp()
        os.environ['LINUX'] = self.linux_temp
        subprocess.check_call(['git', 'init'], stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL,
                              cwd=self.linux_temp)

        for i in range(1, 4):
            subprocess.check_call(['touch', str(i)], cwd=self.linux_temp)
            subprocess.check_call(['git', 'add', str(i)], cwd=self.linux_temp)
            subprocess.check_call(['git', 'commit', '-m', str(i)], stdout=subprocess.DEVNULL,
                                  stderr=subprocess.DEVNULL, cwd=self.linux_temp)

        # Create temporary directory for $CHROMIUMOS_KERNEL
        self.cros_temp = tempfile.mkdtemp()
        os.environ['CHROMIUMOS_KERNEL'] = self.cros_temp
        subprocess.check_call(['git', 'init'], stdout=subprocess.DEVNULL,
                              stderr=subprocess.DEVNULL, cwd=self.cros_temp)

        # # Creates branch that represents a mock of a kernel version
        branch = 'v' + os.path.basename(self.linux_temp)

        subprocess.check_call(['git', 'checkout', '-b', branch], stdout=subprocess.DEVNULL,
                              stderr=subprocess.DEVNULL, cwd=self.cros_temp)

        # Create a commit for branch to be recognized in computer
        subprocess.check_call(['touch', 'file'], stdout=subprocess.DEVNULL,
                              stderr=subprocess.DEVNULL, cwd=self.cros_temp)
        subprocess.check_call(['git', 'add', 'file'], stdout=subprocess.DEVNULL,
                              stderr=subprocess.DEVNULL, cwd=self.cros_temp)
        subprocess.check_call(['git', 'commit', '-m', 'random'], stdout=subprocess.DEVNULL,
                              stderr=subprocess.DEVNULL, cwd=self.cros_temp)

        # Clone LINUX to CHROMIUMOS_KERNEL
        subprocess.check_call(['git', 'clone', self.linux_temp], stdout=subprocess.DEVNULL,
                              stderr=subprocess.DEVNULL, cwd=self.cros_temp)

        # Add extra commit to LINUX
        subprocess.check_call(['touch', '4'], cwd=self.linux_temp)
        subprocess.check_call(['git', 'add', '4'], cwd=self.linux_temp)
        subprocess.check_call(['git', 'commit', '-m', '4'], stdout=subprocess.DEVNULL,
                              stderr=subprocess.DEVNULL, cwd=self.linux_temp)

    def tearDown(self):
        if self.linux:
            os.environ['LINUX'] = self.linux
        else:
            del os.environ['LINUX']

        if self.cros_kernel:
            os.environ['CHROMIUMOS_KERNEL'] = self.cros_kernel
        else:
            del os.environ['CHROMIUMOS_KERNEL']

        subprocess.check_call(['rm', '-rf', self.linux_temp])
        subprocess.check_call(['rm', '-rf', self.cros_temp])

    @mock.patch('cvelib.common.checkout_branch')
    def test_apply_patch(self, _):
        """Unit test for apply_patch"""
        sha = get_sha(self.linux_temp)
        bug_id = '123'
        kernel_versions = [os.path.basename(self.linux_temp)]

        kernels = pa.apply_patch(sha, bug_id, kernel_versions)

        self.assertTrue(kernels[os.path.basename(self.linux_temp)])

    def test_create_commit_message(self):
        """Unit test for create_commit_message."""
        kernel = os.path.basename(self.linux_temp)
        kernel_path = os.path.join(self.cros_temp, kernel)

        sha = get_sha(self.linux_temp)
        bug_id = '123'

        pa.fetch_linux_kernel(kernel_path)

        pa.cherry_pick(kernel_path, sha, bug_id)

        # Retrieves new cherry-picked message
        msg = common.get_commit_message(kernel_path, get_sha(kernel_path))

        check = False
        if 'UPSTREAM:' in msg and 'BUG=' in msg and 'TEST=' in msg:
            check = True

        self.assertTrue(check)

    def test_fetch_linux_kernel(self):
        """Unit test for fetch_linux_kernel."""
        kernel = os.path.basename(self.linux_temp)
        kernel_path = os.path.join(self.cros_temp, kernel)

        linux_expected = self.linux_temp

        linux_actual = pa.fetch_linux_kernel(kernel_path)

        # Checks if fetched from the correct repo.
        self.assertEqual(linux_expected, linux_actual)

    def test_cherry_pick(self):
        """Unit test for cherry_pick."""
        kernel = os.path.basename(self.linux_temp)
        kernel_path = os.path.join(self.cros_temp, kernel)

        sha = get_sha(self.linux_temp)
        bug_id = '123'

        pa.fetch_linux_kernel(kernel_path)

        check = pa.cherry_pick(kernel_path, sha, bug_id)

        self.assertTrue(check)

    def test_create_new_cherry_pick_branch(self):
        """Unit test for create_new_cherry_pick_branch"""
        kernel = os.path.basename(self.linux_temp)
        bug_id = '123'

        pa.create_new_cherry_pick_branch(kernel, bug_id, self.cros_temp)

        # Outputs the current branch
        branch = subprocess.check_output(['git', 'rev-parse', '--abbrev-ref', 'HEAD'],
                                         stderr=subprocess.DEVNULL, cwd=self.cros_temp)

        expected_branch = f'b{bug_id}-{kernel}'

        self.assertEqual(branch.rstrip(), bytes(expected_branch, encoding='utf-8'))

    @mock.patch('cvelib.common.checkout_branch')
    def test_invalid_sha(self, _):
        """Test for passing of invalid commit sha."""
        sha = '123'
        bug = '123'
        kernel_versions = [os.path.basename(self.linux_temp)]

        self.assertRaises(common.CommonException, pa.apply_patch,
                          sha, bug, kernel_versions)

    def test_invalid_linux_path(self):
        """Test for invalid LINUX directory"""
        linux = self.linux_temp
        os.environ['LINUX'] = '/tmp/tmp'

        kernel = os.path.basename(self.linux_temp)
        kernel_path = os.path.join(self.cros_temp, kernel)

        self.assertRaises(pa.PatchApplierException, pa.fetch_linux_kernel,
                          kernel_path)

        os.environ['LINUX'] = linux

    def test_empty_env_variables(self):
        """Test for empty LINUX or CHROMIUMOS_KERNEL environement variables"""
        linux = self.linux_temp
        chros_kernel = self.cros_temp

        sha = get_sha(self.linux_temp)
        bug = '123'
        kernel_versions = [os.path.basename(self.linux_temp)]

        os.environ['LINUX'] = ''

        self.assertRaises(pa.PatchApplierException, pa.apply_patch,
                          sha, bug, kernel_versions)

        os.environ['LINUX'] = linux
        os.environ['CHROMIUMOS_KERNEL'] = ''

        self.assertRaises(pa.PatchApplierException, pa.apply_patch,
                          sha, bug, kernel_versions)

        os.environ['CHROMIUMOS_KERNEL'] = chros_kernel

    def test_invalid_kernel(self):
        """Test for passing of invalid kernel"""
        sha = get_sha(self.linux_temp)
        bug = '123'
        kernel_versions = ['not_a_kernel']

        self.assertRaises(pa.PatchApplierException, pa.apply_patch,
                          sha, bug, kernel_versions)
