#!/usr/bin/env python
#
# Copyright (C) 2017 The Android Open Source Project
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#      http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#

import gzip
import logging
import os
import re
import shutil
import tempfile

from vts.runners.host import asserts
from vts.runners.host import base_test
from vts.runners.host import const
from vts.runners.host import keys
from vts.runners.host import test_runner
from vts.utils.python.controllers import android_device
from vts.utils.python.file import file_utils


class VtsKernelConfigTest(base_test.BaseTestClass):
    """Test case which check config options in /proc/config.gz.

    Attributes:
        _temp_dir: The temporary directory to which /proc/config.gz is copied.
    """

    PROC_FILE_PATH = "/proc/config.gz"
    KERNEL_CONFIG_FILE_PATH = "vts/testcases/kernel/config/data"
    SUPPORTED_KERNEL_VERSIONS = ["3.18", "4.4", "4.9"]

    def setUpClass(self):
        required_params = [
            keys.ConfigKeys.IKEY_DATA_FILE_PATH
        ]
        self.getUserParams(required_params)
        self.dut = self.registerController(android_device)[0]
        self.dut.shell.InvokeTerminal(
            "KernelConfigTest")  # creates a remote shell instance.
        self.shell = self.dut.shell.KernelConfigTest
        self._temp_dir = tempfile.mkdtemp()

    def checkKernelVersion(self):
        """Validate the kernel version of DUT is a valid O kernel version.

        Returns:
            string, kernel version of device
        """
        cmd = "uname -a"
        results = self.shell.Execute(cmd)
        logging.info("Shell command '%s' results: %s", cmd, results)

        match = re.search(r"\d+\.\d+", results[const.STDOUT][0])
        if match is None:
            asserts.fail("Failed to detect kernel version of device.")
        else:
            kernel_version = match.group(0)
        logging.info("Detected kernel version: %s", kernel_version)

        asserts.assertTrue(kernel_version in self.SUPPORTED_KERNEL_VERSIONS,
                           "Detected kernel version '%s' is not one of %s"
                           % (kernel_version, self.SUPPORTED_KERNEL_VERSIONS))

        return kernel_version

    def parseConfigFileToDict(self, file):
        """Parse kernel config file to a dictionary.

        Args:
            file: file object, android-base.cfg or unzipped /proc/config.gz

        Returns:
            dict: {config_name: config_state}
        """
        config_lines = [line.rstrip("\n") for line in file.readlines()]
        configs = dict()

        for line in config_lines:
            if line.startswith("#") and line.endswith("is not set"):
                match = re.search(r"CONFIG_\S+", line)
                if match is None:
                    asserts.fail("Failed to parse config file")
                else:
                    config_name = match.group(0)
                config_state = "n"
            elif line.startswith("CONFIG_"):
                config_name, config_state = line.split("=", 1)
                if config_state.startswith(("'", '"')):
                    config_state = config_state[1:-1]
            else:
                continue
            configs[config_name] = config_state

        return configs

    def testKernelConfigs(self):
        """Ensures all configs conform to android-base.cfg requirements.

        Detects kernel version of device and validates against appropriate
        Common Android Kernel android-base.cfg.
        """
        logging.info("Testing existence of %s" % self.PROC_FILE_PATH)
        file_utils.assertPermissionsAndExistence(
            self.shell, self.PROC_FILE_PATH, file_utils.IsReadOnly)

        logging.info("Validating kernel version of device.")
        kernel_version = self.checkKernelVersion()

        config_file_path = os.path.join(self.data_file_path,
            self.KERNEL_CONFIG_FILE_PATH, "android-" + kernel_version,
            "android-base.cfg")
        with open(config_file_path, 'r') as config_file:
            configs = self.parseConfigFileToDict(config_file)

        self.dut.adb.pull("%s %s" % (self.PROC_FILE_PATH, self._temp_dir))
        logging.info("Adb pull %s to %s", self.PROC_FILE_PATH, self._temp_dir)

        localpath = os.path.join(self._temp_dir, "config.gz")
        with gzip.open(localpath, "rb") as device_config_file:
            device_configs = self.parseConfigFileToDict(device_config_file)

        should_be_enabled = []
        should_not_be_set = []
        incorrect_config_state = []
        for config_name, config_state in configs.iteritems():
            if (config_state == "y" and
                (config_name not in device_configs or
                 device_configs[config_name] not in ("y", "m"))):
                should_be_enabled.append(config_name)
            elif (config_state == "n" and (config_name in device_configs) and
                  device_configs[config_name] != "n"):
                should_not_be_set.append(config_name + "=" +
                                         device_configs[config_name])
            elif (config_name in device_configs and
                  device_configs[config_name] != config_state):
                incorrect_config_state.append(config_name + "=" +
                                              device_configs[config_name])

        asserts.assertTrue(
            len(should_be_enabled) == 0 and len(should_not_be_set) == 0 and
            len(incorrect_config_state) == 0,
            ("The following kernel configs should be enabled: [%s]\n"
             "The following kernel configs should not be set: [%s]\n"
             "THe following kernel configs have incorrect state: [%s]") %
            (", ".join(should_be_enabled), ", ".join(should_not_be_set),
             ", ".join(incorrect_config_state)))

    def tearDownClass(self):
        """Deletes the temporary directory."""
        logging.info("Delete %s", self._temp_dir)
        shutil.rmtree(self._temp_dir)


if __name__ == "__main__":
    test_runner.main()
