#!/usr/bin/python3
# SPDX-License-Identifier: GPL-2.0
import unittest
import os
import time
import glob
import fcntl
try:
    import ioctl_opt as ioctl
except ImportError:
    ioctl = None
    pass
from dbc import *

# Artificial delay between set commands
SET_DELAY = 0.5


class invalid_param(ctypes.Structure):
    _fields_ = [
        ("data", ctypes.c_uint8),
    ]


def system_is_secured() -> bool:
    fused_part = glob.glob("/sys/bus/pci/drivers/ccp/**/fused_part")[0]
    if os.path.exists(fused_part):
        with open(fused_part, "r") as r:
            return int(r.read()) == 1
    return True


class DynamicBoostControlTest(unittest.TestCase):
    def __init__(self, data) -> None:
        self.d = None
        self.signature = b"FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
        self.uid = b"1111111111111111"
        super().__init__(data)

    def setUp(self) -> None:
        self.d = open(DEVICE_NODE)
        return super().setUp()

    def tearDown(self) -> None:
        if self.d:
            self.d.close()
        return super().tearDown()


class TestUnsupportedSystem(DynamicBoostControlTest):
    def setUp(self) -> None:
        if os.path.exists(DEVICE_NODE):
            self.skipTest("system is supported")
        with self.assertRaises(FileNotFoundError) as error:
            super().setUp()
        self.assertEqual(error.exception.errno, 2)

    def test_unauthenticated_nonce(self) -> None:
        """fetch unauthenticated nonce"""
        with self.assertRaises(ValueError) as error:
            get_nonce(self.d, None)


class TestInvalidIoctls(DynamicBoostControlTest):
    def __init__(self, data) -> None:
        self.data = invalid_param()
        self.data.data = 1
        super().__init__(data)

    def setUp(self) -> None:
        if not os.path.exists(DEVICE_NODE):
            self.skipTest("system is unsupported")
        if not ioctl:
            self.skipTest("unable to test IOCTLs without ioctl_opt")

        return super().setUp()

    def test_invalid_nonce_ioctl(self) -> None:
        """tries to call get_nonce ioctl with invalid data structures"""

        # 0x1 (get nonce), and invalid data
        INVALID1 = ioctl.IOWR(ord("D"), 0x01, invalid_param)
        with self.assertRaises(OSError) as error:
            fcntl.ioctl(self.d, INVALID1, self.data, True)
        self.assertEqual(error.exception.errno, 22)

    def test_invalid_setuid_ioctl(self) -> None:
        """tries to call set_uid ioctl with invalid data structures"""

        # 0x2 (set uid), and invalid data
        INVALID2 = ioctl.IOW(ord("D"), 0x02, invalid_param)
        with self.assertRaises(OSError) as error:
            fcntl.ioctl(self.d, INVALID2, self.data, True)
        self.assertEqual(error.exception.errno, 22)

    def test_invalid_setuid_rw_ioctl(self) -> None:
        """tries to call set_uid ioctl with invalid data structures"""

        # 0x2 as RW (set uid), and invalid data
        INVALID3 = ioctl.IOWR(ord("D"), 0x02, invalid_param)
        with self.assertRaises(OSError) as error:
            fcntl.ioctl(self.d, INVALID3, self.data, True)
        self.assertEqual(error.exception.errno, 22)

    def test_invalid_param_ioctl(self) -> None:
        """tries to call param ioctl with invalid data structures"""
        # 0x3 (param), and invalid data
        INVALID4 = ioctl.IOWR(ord("D"), 0x03, invalid_param)
        with self.assertRaises(OSError) as error:
            fcntl.ioctl(self.d, INVALID4, self.data, True)
        self.assertEqual(error.exception.errno, 22)

    def test_invalid_call_ioctl(self) -> None:
        """tries to call the DBC ioctl with invalid data structures"""
        # 0x4, and invalid data
        INVALID5 = ioctl.IOWR(ord("D"), 0x04, invalid_param)
        with self.assertRaises(OSError) as error:
            fcntl.ioctl(self.d, INVALID5, self.data, True)
        self.assertEqual(error.exception.errno, 22)


class TestInvalidSignature(DynamicBoostControlTest):
    def setUp(self) -> None:
        if not os.path.exists(DEVICE_NODE):
            self.skipTest("system is unsupported")
        if not system_is_secured():
            self.skipTest("system is unfused")
        return super().setUp()

    def test_unauthenticated_nonce(self) -> None:
        """fetch unauthenticated nonce"""
        get_nonce(self.d, None)

    def test_multiple_unauthenticated_nonce(self) -> None:
        """ensure state machine always returns nonce"""
        for count in range(0, 2):
            get_nonce(self.d, None)

    def test_authenticated_nonce(self) -> None:
        """fetch authenticated nonce"""
        get_nonce(self.d, None)
        with self.assertRaises(OSError) as error:
            get_nonce(self.d, self.signature)
        self.assertEqual(error.exception.errno, 22)

    def test_set_uid(self) -> None:
        """set uid"""
        get_nonce(self.d, None)
        with self.assertRaises(OSError) as error:
            set_uid(self.d, self.uid, self.signature)
        self.assertEqual(error.exception.errno, 1)

    def test_get_param(self) -> None:
        """fetch a parameter"""
        with self.assertRaises(OSError) as error:
            process_param(self.d, PARAM_GET_SOC_PWR_CUR, self.signature)
        self.assertEqual(error.exception.errno, 11)

    def test_set_param(self) -> None:
        """set a parameter"""
        with self.assertRaises(OSError) as error:
            process_param(self.d, PARAM_SET_PWR_CAP, self.signature, 1000)
        self.assertEqual(error.exception.errno, 11)


class TestUnFusedSystem(DynamicBoostControlTest):
    def setup_identity(self) -> None:
        """sets up the identity of the caller"""
        # if already authenticated these may fail
        try:
            get_nonce(self.d, None)
        except PermissionError:
            pass
        try:
            set_uid(self.d, self.uid, self.signature)
        except BlockingIOError:
            pass
        try:
            get_nonce(self.d, self.signature)
        except PermissionError:
            pass

    def setUp(self) -> None:
        if not os.path.exists(DEVICE_NODE):
            self.skipTest("system is unsupported")
        if system_is_secured():
            self.skipTest("system is fused")
        super().setUp()
        self.setup_identity()
        time.sleep(SET_DELAY)

    def test_get_valid_param(self) -> None:
        """fetch all possible parameters"""
        # SOC power
        soc_power_max = process_param(self.d, PARAM_GET_SOC_PWR_MAX, self.signature)
        soc_power_min = process_param(self.d, PARAM_GET_SOC_PWR_MIN, self.signature)
        self.assertGreater(soc_power_max[0], soc_power_min[0])

        # fmax
        fmax_max = process_param(self.d, PARAM_GET_FMAX_MAX, self.signature)
        fmax_min = process_param(self.d, PARAM_GET_FMAX_MIN, self.signature)
        self.assertGreater(fmax_max[0], fmax_min[0])

        # cap values
        keys = {
            "fmax-cap": PARAM_GET_FMAX_CAP,
            "power-cap": PARAM_GET_PWR_CAP,
            "current-temp": PARAM_GET_CURR_TEMP,
            "soc-power-cur": PARAM_GET_SOC_PWR_CUR,
        }
        for k in keys:
            result = process_param(self.d, keys[k], self.signature)
            self.assertGreater(result[0], 0)

    def test_get_invalid_param(self) -> None:
        """fetch an invalid parameter"""
        try:
            set_uid(self.d, self.uid, self.signature)
        except OSError:
            pass
        with self.assertRaises(OSError) as error:
            process_param(self.d, (0xF,), self.signature)
        self.assertEqual(error.exception.errno, 22)

    def test_set_fmax(self) -> None:
        """get/set fmax limit"""
        # fetch current
        original = process_param(self.d, PARAM_GET_FMAX_CAP, self.signature)

        # set the fmax
        target = original[0] - 100
        process_param(self.d, PARAM_SET_FMAX_CAP, self.signature, target)
        time.sleep(SET_DELAY)
        new = process_param(self.d, PARAM_GET_FMAX_CAP, self.signature)
        self.assertEqual(new[0], target)

        # revert back to current
        process_param(self.d, PARAM_SET_FMAX_CAP, self.signature, original[0])
        time.sleep(SET_DELAY)
        cur = process_param(self.d, PARAM_GET_FMAX_CAP, self.signature)
        self.assertEqual(cur[0], original[0])

    def test_set_power_cap(self) -> None:
        """get/set power cap limit"""
        # fetch current
        original = process_param(self.d, PARAM_GET_PWR_CAP, self.signature)

        # set the fmax
        target = original[0] - 10
        process_param(self.d, PARAM_SET_PWR_CAP, self.signature, target)
        time.sleep(SET_DELAY)
        new = process_param(self.d, PARAM_GET_PWR_CAP, self.signature)
        self.assertEqual(new[0], target)

        # revert back to current
        process_param(self.d, PARAM_SET_PWR_CAP, self.signature, original[0])
        time.sleep(SET_DELAY)
        cur = process_param(self.d, PARAM_GET_PWR_CAP, self.signature)
        self.assertEqual(cur[0], original[0])

    def test_set_3d_graphics_mode(self) -> None:
        """set/get 3d graphics mode"""
        # these aren't currently implemented but may be some day
        # they are *expected* to fail
        with self.assertRaises(OSError) as error:
            process_param(self.d, PARAM_GET_GFX_MODE, self.signature)
        self.assertEqual(error.exception.errno, 2)

        time.sleep(SET_DELAY)

        with self.assertRaises(OSError) as error:
            process_param(self.d, PARAM_SET_GFX_MODE, self.signature, 1)
        self.assertEqual(error.exception.errno, 2)


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