import unittest

from src.odoo_env_config.api import Env
from src.odoo_env_config.section.limit_section import LimitOdooConfigSection


class TestLimitOdooConfigSection(unittest.TestCase):
    def test_no_value(self):
        conf = LimitOdooConfigSection()
        self.assertEqual(0, conf.limit_request)
        self.assertEqual(0, conf.limit_time_cpu)
        self.assertEqual(0, conf.limit_time_real)
        self.assertEqual(0, conf.osv_memory_count_limit)
        self.assertEqual(0, conf.limit_memory_hard)
        self.assertEqual(0, conf.limit_memory_soft)

    def test_value(self):
        conf = LimitOdooConfigSection().init(
            Env(
                {
                    "LIMIT_REQUEST": str(1),
                    "LIMIT_TIME_CPU": str(2),
                    "LIMIT_TIME_REAL": str(3),
                    "OSV_MEMORY_COUNT_LIMIT": str(4),
                    "LIMIT_MEMORY_HARD": str(5),
                    "LIMIT_MEMORY_SOFT": str(6),
                }
            )
        )
        self.assertEqual(1, conf.limit_request)
        self.assertEqual(2, conf.limit_time_cpu)
        self.assertEqual(3, conf.limit_time_real)
        self.assertEqual(4, conf.osv_memory_count_limit)
        self.assertEqual(5, conf.limit_memory_hard)
        self.assertEqual(6, conf.limit_memory_soft)

    def test_global_hard_default_worker(self):
        conf = LimitOdooConfigSection().init(
            Env(
                {
                    "GLOBAL_LIMIT_MEMORY_HARD": str(1000),
                }
            )
        )
        self.assertEqual(1000, conf.limit_memory_hard)
        self.assertEqual(0, conf.limit_request)
        self.assertEqual(0, conf.limit_time_cpu)
        self.assertEqual(0, conf.limit_time_real)
        self.assertEqual(0, conf.osv_memory_count_limit)
        self.assertEqual(0, conf.limit_memory_soft)

    def test_global_hard_no_worker(self):
        """
        by default 2 worker cron and 1 worker http so we force to 0 worker http and worker cron
        so <GLOBAL_LIMIT_MEMORY_HARD> is divide by 3 (integer way with '//')
        """
        conf = LimitOdooConfigSection().init(
            Env(
                {
                    "WORKER_HTTP": str(0),
                    "WORKER_CRON": str(0),
                    "GLOBAL_LIMIT_MEMORY_HARD": str(1000),
                }
            )
        )
        self.assertEqual(1000, conf.limit_memory_hard)
        self.assertEqual(0, conf.limit_request)
        self.assertEqual(0, conf.limit_time_cpu)
        self.assertEqual(0, conf.limit_time_real)
        self.assertEqual(0, conf.osv_memory_count_limit)
        self.assertEqual(0, conf.limit_memory_soft)

    def test_global_soft_default_worker(self):
        """
        by default 2 worker cron and 1 worker http
        so <GLOBAL_LIMIT_MEMORY_SOFT> is divide by 3 (integer way with '//')
        """
        conf = LimitOdooConfigSection().init(
            Env(
                {
                    "GLOBAL_LIMIT_MEMORY_SOFT": str(1000),
                }
            )
        )
        self.assertEqual(1000, conf.limit_memory_soft)
        self.assertEqual(0, conf.limit_request)
        self.assertEqual(0, conf.limit_time_cpu)
        self.assertEqual(0, conf.limit_time_real)
        self.assertEqual(0, conf.osv_memory_count_limit)
        self.assertEqual(0, conf.limit_memory_hard)

    def test_global_soft_priority(self):
        """
        check priority between <GLOBAL_LIMIT_MEMORY_SOFT> and <LIMIT_MEMORY_SOFT>
        LIMIT_MEMORY_SOFT > GLOBAL_LIMIT_MEMORY_SOFT
        """
        conf = LimitOdooConfigSection().init(
            Env(
                {
                    "LIMIT_MEMORY_SOFT": str(100),
                    "GLOBAL_LIMIT_MEMORY_SOFT": str(1000),
                }
            )
        )
        self.assertEqual(100, conf.limit_memory_soft)
        self.assertEqual(0, conf.limit_request)
        self.assertEqual(0, conf.limit_time_cpu)
        self.assertEqual(0, conf.limit_time_real)
        self.assertEqual(0, conf.osv_memory_count_limit)
        self.assertEqual(0, conf.limit_memory_hard)

    def test_global_hard_priority(self):
        """
        check priority between <GLOBAL_LIMIT_MEMORY_HARD> and <LIMIT_MEMORY_HARD>
        LIMIT_MEMORY_HARD > GLOBAL_LIMIT_MEMORY_HARD
        """
        conf = LimitOdooConfigSection().init(
            Env(
                {
                    "LIMIT_MEMORY_HARD": str(100),
                    "GLOBAL_LIMIT_MEMORY_HARD": str(1000),
                }
            )
        )
        self.assertEqual(100, conf.limit_memory_hard)
        self.assertEqual(0, conf.limit_request)
        self.assertEqual(0, conf.limit_time_cpu)
        self.assertEqual(0, conf.limit_time_real)
        self.assertEqual(0, conf.osv_memory_count_limit)

    def test_global_soft_no_worker(self):
        """
        `GLOBAL_LIMIT_MEMORY_SOFT` is divide by 3 (integer way with '//')
        """
        conf = LimitOdooConfigSection().init(
            Env(
                {
                    "WORKER_HTTP": str(2),
                    "WORKER_CRON": str(1),
                    "GLOBAL_LIMIT_MEMORY_SOFT": str(1000),
                    "LIMIT_MEMORY_HARD": str(200),
                }
            )
        )
        self.assertEqual(333, conf.limit_memory_soft)
        self.assertEqual(0, conf.limit_request)
        self.assertEqual(0, conf.limit_time_cpu)
        self.assertEqual(0, conf.limit_time_real)
        self.assertEqual(0, conf.osv_memory_count_limit)
        self.assertEqual(200, conf.limit_memory_hard)
