# Copyright 2023 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.
"""Tests for apex_sepolicy_tests"""

import re
import shutil
import tempfile
import unittest

import apex_sepolicy_tests as apex
import policy


# pylint: disable=missing-docstring
class ApexSepolicyTests(unittest.TestCase):

    @classmethod
    def setUpClass(cls) -> None:
        cls.temp_dir = tempfile.mkdtemp()
        lib_path = apex.extract_data(apex.LIBSEPOLWRAP, cls.temp_dir)
        policy_path = apex.extract_data('precompiled_sepolicy', cls.temp_dir)
        cls.pol = policy.Policy(policy_path, None,  lib_path)

    @classmethod
    def tearDownClass(cls) -> None:
        shutil.rmtree(cls.temp_dir)

    # helpers

    @property
    def pol(self):
        return self.__class__.pol

    def assert_ok(self, line: str):
        errors = apex.check_line(self.pol, line)
        self.assertEqual(errors, [], "Should be no errors")

    def assert_error(self, line: str, expected_error: str):
        pattern = re.compile(expected_error)
        errors = apex.check_line(self.pol, line)
        for err in errors:
            if re.search(pattern, err):
                return
        self.fail(f"Expected error '{expected_error}' is not found in {errors}")

    # tests

    def test_parse_lines(self):
        self.assert_ok('# commented line')
        self.assert_ok('') # empty line
        self.assert_error('./path1 invalid_contexts',
                          r'Error: invalid file_contexts: .*')
        self.assert_error('./path1 u:object_r:vendor_file',
                          r'Error: invalid file_contexts: .*')
        self.assert_ok('./path1 u:object_r:vendor_file:s0')

    def test_vintf(self):
        self.assert_ok('./etc/vintf/fragment.xml u:object_r:vendor_configs_file:s0')
        self.assert_error('./etc/vintf/fragment.xml u:object_r:vendor_file:s0',
                          r'Error: \./etc/vintf/fragment\.xml: .* can\'t read')

    def test_permissions(self):
        self.assert_ok('./etc/permissions/permisssion.xml u:object_r:vendor_configs_file:s0')
        self.assert_error('./etc/permissions/permisssion.xml u:object_r:vendor_file:s0',
                          r'Error: \./etc/permissions/permisssion.xml: .* can\'t read')

    def test_initscripts(self):
        # init reads .rc file
        self.assert_ok('./etc/init.rc u:object_r:vendor_file:s0')
        self.assert_error('./etc/init.rc u:object_r:unknown:s0',
                          r'Error: .* can\'t read')
        # init reads .#rc file
        self.assert_ok('./etc/init.32rc u:object_r:vendor_file:s0')
        self.assert_error('./etc/init.32rc u:object_r:unknown:s0',
                          r'Error: .* can\'t read')
        # init skips file with unknown extension => no errors
        self.assert_ok('./etc/init.x32rc u:object_r:vendor_file:s0')
        self.assert_ok('./etc/init.x32rc u:object_r:unknown:s0')

    def test_linkerconfig(self):
        self.assert_ok('./etc/linker.config.pb u:object_r:system_file:s0')
        self.assert_ok('./etc/linker.config.pb u:object_r:linkerconfig_file:s0')
        self.assert_error('./etc/linker.config.pb u:object_r:vendor_file:s0',
                        r'Error: .*linkerconfig.* can\'t read')
        self.assert_error('./ u:object_r:apex_data_file:s0',
                        r'Error: .*linkerconfig.* can\'t read')

if __name__ == '__main__':
    unittest.main(verbosity=2)
