#!/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 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 test_runner
from vts.testcases.kernel.api.proc import required_kernel_configs as configs
from vts.utils.python.controllers import android_device

from ProcMemInfoTest import ProcMemInfoTest
from ProcZoneInfoTest import ProcZoneInfoTest
from ProcShowUidStatTest import ProcShowUidStatTest
from ProcCpuInfoTest import ProcCpuInfoTest
from ProcStatTest import ProcStatTest
from ProcVmallocInfoTest import ProcVmallocInfoTest
from ProcRemoveUidRangeTest import ProcRemoveUidRangeTest
from ProcQtaguidCtrlTest import ProcQtaguidCtrlTest
from ProcMapsTest import ProcMapsTest
from ProcSimpleFileTests import ProcKptrRestrictTest
from ProcSimpleFileTests import ProcMmapMinAddrTest
from ProcSimpleFileTests import ProcMmapRndBitsTest
from ProcSimpleFileTests import ProcMmapRndCompatBitsTest
from ProcSimpleFileTests import ProcOverCommitMemoryTest
from ProcSimpleFileTests import ProcRandomizeVaSpaceTest

TEST_OBJECTS = {
    ProcMemInfoTest(),
    ProcZoneInfoTest(),
    ProcShowUidStatTest(),
    ProcCpuInfoTest(),
    ProcStatTest(),
    ProcVmallocInfoTest(),
    ProcKptrRestrictTest(),
    ProcRandomizeVaSpaceTest(),
    ProcMmapMinAddrTest(),
    ProcMmapRndBitsTest(),
    ProcMmapRndCompatBitsTest(),
    ProcOverCommitMemoryTest(),
    ProcRemoveUidRangeTest(),
    ProcQtaguidCtrlTest(),
    ProcMapsTest(),
}

class KernelProcFileApiTest(base_test.BaseTestClass):
    """Test cases which check content of proc files.

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

    PROC_FILE_PATH = "/proc/config.gz"

    def setUpClass(self):
        self.dut = self.registerController(android_device)[0]
        self.dut.shell.InvokeTerminal(
            "KernelApiTest")  # creates a remote shell instance.
        self.shell = self.dut.shell.KernelApiTest
        self._temp_dir = tempfile.mkdtemp()

    def runProcFileTest(self, test_object):
        """Reads from the file and checks that it parses and the content is valid.

        Args:
            test_object: inherits KernelProcFileTestBase, contains the test functions
        """
        logging.info("Testing format of %s" % (test_object.get_path()))
        asserts.assertTrue(
            test_object.prepare_test(self.shell), "Setup failed!")

        file_content = self.ReadFileContent(test_object.get_path())
        try:
            parse_result = test_object.parse_contents(file_content)
        except SyntaxError as e:
            asserts.fail("Failed to parse! " + str(e))
        asserts.assertTrue(
            test_object.result_correct(parse_result), "Results not valid!")

    def generateProcFileTests(self):
        """Run all proc file tests."""
        self.runGeneratedTests(test_func=self.runProcFileTest,
                settings=TEST_OBJECTS,
                name_func=lambda test_obj: "test" + test_obj.__class__.__name__)

    def ReadFileContent(self, filepath):
        """Read the content of a file and perform assertions.

        Args:
            filepath: string, path to file

        Returns:
            string, content of file
        """
        cmd = "cat %s" % filepath
        results = self.shell.Execute(cmd)
        logging.info("%s: Shell command '%s' results: %s", filepath, cmd,
                     results)

        # checks the exit code
        asserts.assertEqual(
            results[const.EXIT_CODE][0], 0,
            "%s: Error happened while reading the file." % filepath)

        return results[const.STDOUT][0]

    def testCheckConfigs(self):
        """Ensures all options from android-base.cfg are enabled."""
        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 f:
            device_config_lines = [line.rstrip("\n") for line in f.readlines()]

        device_configs = dict()
        for line in device_config_lines:
            if line == "" or line.startswith("#"):
                continue
            config_name, config_state = line.split("=", 1)
            device_configs[config_name] = config_state

        should_be_enabled = []
        should_not_be_set = []
        for config_name, config_state in configs.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:
                should_not_be_set.append(config_name + "=" +
                                         device_configs[config_name])

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

    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()
