# SPDX-License-Identifier: GPL-2.0
#
# Copyright (C) 2018 Masahiro Yamada <yamada.masahiro@socionext.com>
#

"""
Kconfig unit testing framework.

This provides fixture functions commonly used from test files.
"""

import os
import pytest
import shutil
import subprocess
import tempfile

CONF_PATH = os.path.abspath(os.path.join('scripts', 'kconfig', 'conf'))


class Conf:
    """Kconfig runner and result checker.

    This class provides methods to run text-based interface of Kconfig
    (scripts/kconfig/conf) and retrieve the resulted configuration,
    stdout, and stderr.  It also provides methods to compare those
    results with expectations.
    """

    def __init__(self, request):
        """Create a new Conf instance.

        request: object to introspect the requesting test module
        """
        # the directory of the test being run
        self._test_dir = os.path.dirname(str(request.fspath))

    # runners
    def _run_conf(self, mode, dot_config=None, out_file='.config',
                  interactive=False, in_keys=None, extra_env={}):
        """Run text-based Kconfig executable and save the result.

        mode: input mode option (--oldaskconfig, --defconfig=<file> etc.)
        dot_config: .config file to use for configuration base
        out_file: file name to contain the output config data
        interactive: flag to specify the interactive mode
        in_keys: key inputs for interactive modes
        extra_env: additional environments
        returncode: exit status of the Kconfig executable
        """
        command = [CONF_PATH, mode, 'Kconfig']

        # Override 'srctree' environment to make the test as the top directory
        extra_env['srctree'] = self._test_dir

        # Run Kconfig in a temporary directory.
        # This directory is automatically removed when done.
        with tempfile.TemporaryDirectory() as temp_dir:

            # if .config is given, copy it to the working directory
            if dot_config:
                shutil.copyfile(os.path.join(self._test_dir, dot_config),
                                os.path.join(temp_dir, '.config'))

            ps = subprocess.Popen(command,
                                  stdin=subprocess.PIPE,
                                  stdout=subprocess.PIPE,
                                  stderr=subprocess.PIPE,
                                  cwd=temp_dir,
                                  env=dict(os.environ, **extra_env))

            # If input key sequence is given, feed it to stdin.
            if in_keys:
                ps.stdin.write(in_keys.encode('utf-8'))

            while ps.poll() is None:
                # For interactive modes such as oldaskconfig, oldconfig,
                # send 'Enter' key until the program finishes.
                if interactive:
                    ps.stdin.write(b'\n')

            self.retcode = ps.returncode
            self.stdout = ps.stdout.read().decode()
            self.stderr = ps.stderr.read().decode()

            # Retrieve the resulted config data only when .config is supposed
            # to exist.  If the command fails, the .config does not exist.
            # 'listnewconfig' does not produce .config in the first place.
            if self.retcode == 0 and out_file:
                with open(os.path.join(temp_dir, out_file)) as f:
                    self.config = f.read()
            else:
                self.config = None

        # Logging:
        # Pytest captures the following information by default.  In failure
        # of tests, the captured log will be displayed.  This will be useful to
        # figure out what has happened.

        print("[command]\n{}\n".format(' '.join(command)))

        print("[retcode]\n{}\n".format(self.retcode))

        print("[stdout]")
        print(self.stdout)

        print("[stderr]")
        print(self.stderr)

        if self.config is not None:
            print("[output for '{}']".format(out_file))
            print(self.config)

        return self.retcode

    def oldaskconfig(self, dot_config=None, in_keys=None):
        """Run oldaskconfig.

        dot_config: .config file to use for configuration base (optional)
        in_key: key inputs (optional)
        returncode: exit status of the Kconfig executable
        """
        return self._run_conf('--oldaskconfig', dot_config=dot_config,
                              interactive=True, in_keys=in_keys)

    def oldconfig(self, dot_config=None, in_keys=None):
        """Run oldconfig.

        dot_config: .config file to use for configuration base (optional)
        in_key: key inputs (optional)
        returncode: exit status of the Kconfig executable
        """
        return self._run_conf('--oldconfig', dot_config=dot_config,
                              interactive=True, in_keys=in_keys)

    def olddefconfig(self, dot_config=None):
        """Run olddefconfig.

        dot_config: .config file to use for configuration base (optional)
        returncode: exit status of the Kconfig executable
        """
        return self._run_conf('--olddefconfig', dot_config=dot_config)

    def defconfig(self, defconfig):
        """Run defconfig.

        defconfig: defconfig file for input
        returncode: exit status of the Kconfig executable
        """
        defconfig_path = os.path.join(self._test_dir, defconfig)
        return self._run_conf('--defconfig={}'.format(defconfig_path))

    def _allconfig(self, mode, all_config):
        if all_config:
            all_config_path = os.path.join(self._test_dir, all_config)
            extra_env = {'KCONFIG_ALLCONFIG': all_config_path}
        else:
            extra_env = {}

        return self._run_conf('--{}config'.format(mode), extra_env=extra_env)

    def allyesconfig(self, all_config=None):
        """Run allyesconfig.

        all_config: fragment config file for KCONFIG_ALLCONFIG (optional)
        returncode: exit status of the Kconfig executable
        """
        return self._allconfig('allyes', all_config)

    def allmodconfig(self, all_config=None):
        """Run allmodconfig.

        all_config: fragment config file for KCONFIG_ALLCONFIG (optional)
        returncode: exit status of the Kconfig executable
        """
        return self._allconfig('allmod', all_config)

    def allnoconfig(self, all_config=None):
        """Run allnoconfig.

        all_config: fragment config file for KCONFIG_ALLCONFIG (optional)
        returncode: exit status of the Kconfig executable
        """
        return self._allconfig('allno', all_config)

    def alldefconfig(self, all_config=None):
        """Run alldefconfig.

        all_config: fragment config file for KCONFIG_ALLCONFIG (optional)
        returncode: exit status of the Kconfig executable
        """
        return self._allconfig('alldef', all_config)

    def randconfig(self, all_config=None):
        """Run randconfig.

        all_config: fragment config file for KCONFIG_ALLCONFIG (optional)
        returncode: exit status of the Kconfig executable
        """
        return self._allconfig('rand', all_config)

    def savedefconfig(self, dot_config):
        """Run savedefconfig.

        dot_config: .config file for input
        returncode: exit status of the Kconfig executable
        """
        return self._run_conf('--savedefconfig', out_file='defconfig')

    def listnewconfig(self, dot_config=None):
        """Run listnewconfig.

        dot_config: .config file to use for configuration base (optional)
        returncode: exit status of the Kconfig executable
        """
        return self._run_conf('--listnewconfig', dot_config=dot_config,
                              out_file=None)

    # checkers
    def _read_and_compare(self, compare, expected):
        """Compare the result with expectation.

        compare: function to compare the result with expectation
        expected: file that contains the expected data
        """
        with open(os.path.join(self._test_dir, expected)) as f:
            expected_data = f.read()
        return compare(self, expected_data)

    def _contains(self, attr, expected):
        return self._read_and_compare(
                                    lambda s, e: getattr(s, attr).find(e) >= 0,
                                    expected)

    def _matches(self, attr, expected):
        return self._read_and_compare(lambda s, e: getattr(s, attr) == e,
                                      expected)

    def config_contains(self, expected):
        """Check if resulted configuration contains expected data.

        expected: file that contains the expected data
        returncode: True if result contains the expected data, False otherwise
        """
        return self._contains('config', expected)

    def config_matches(self, expected):
        """Check if resulted configuration exactly matches expected data.

        expected: file that contains the expected data
        returncode: True if result matches the expected data, False otherwise
        """
        return self._matches('config', expected)

    def stdout_contains(self, expected):
        """Check if resulted stdout contains expected data.

        expected: file that contains the expected data
        returncode: True if result contains the expected data, False otherwise
        """
        return self._contains('stdout', expected)

    def stdout_matches(self, expected):
        """Check if resulted stdout exactly matches expected data.

        expected: file that contains the expected data
        returncode: True if result matches the expected data, False otherwise
        """
        return self._matches('stdout', expected)

    def stderr_contains(self, expected):
        """Check if resulted stderr contains expected data.

        expected: file that contains the expected data
        returncode: True if result contains the expected data, False otherwise
        """
        return self._contains('stderr', expected)

    def stderr_matches(self, expected):
        """Check if resulted stderr exactly matches expected data.

        expected: file that contains the expected data
        returncode: True if result matches the expected data, False otherwise
        """
        return self._matches('stderr', expected)


@pytest.fixture(scope="module")
def conf(request):
    """Create a Conf instance and provide it to test functions."""
    return Conf(request)
