import logging
import unittest
from types import SimpleNamespace
from urllib.parse import urlparse

from sglang.srt.utils import kill_process_tree
from sglang.test.ascend.npu_eval_accuracy_kit import _is_pr_pipeline, run_npu_pr_smoke
from sglang.test.ascend.test_ascend_utils import (
    QWEN3_30B_A3B_INSTRUCT_2507_INT4_AUTOROUND_WEIGHTS_PATH,
)
from sglang.test.ci.ci_register import register_npu_ci
from sglang.test.few_shot_gsm8k import run_eval as run_eval_few_shot_gsm8k
from sglang.test.test_utils import (
    DEFAULT_URL_FOR_TEST,
    CustomTestCase,
    popen_launch_server,
)

register_npu_ci(est_time=400, suite="stage-b-test-1-npu-a3", nightly=False)
register_npu_ci(est_time=400, suite="nightly-1-npu-a3", nightly=True)

logger = logging.getLogger(__name__)

TEST_MODEL_MATRIX = {
    QWEN3_30B_A3B_INSTRUCT_2507_INT4_AUTOROUND_WEIGHTS_PATH: {
        "accuracy": 0.85,
    },
}


class TestAscendAutoRoundMoE(CustomTestCase):

    @classmethod
    def setUpClass(cls):
        cls.models = TEST_MODEL_MATRIX.keys()
        cls.base_url = DEFAULT_URL_FOR_TEST
        cls.url = urlparse(DEFAULT_URL_FOR_TEST)
        cls.common_args = [
            "--trust-remote-code",
            "--mem-fraction-static",
            0.8,
            "--attention-backend",
            "ascend",
            "--quantization",
            "auto-round",
        ]

    def test_a_gsm8k(self):
        for model in self.models:
            with self.subTest(model=model):
                process = popen_launch_server(
                    model,
                    self.base_url,
                    timeout=3600,
                    other_args=[
                        *self.common_args,
                    ],
                )

                try:
                    if _is_pr_pipeline:
                        run_npu_pr_smoke(self.base_url)
                    else:
                        logger.info(f"##=== Testing accuracy: {model} ===##")

                        args = SimpleNamespace(
                            num_shots=5,
                            data_path=None,
                            num_questions=1319,
                            max_new_tokens=512,
                            parallel=128,
                            host=f"http://{self.url.hostname}",
                            port=int(self.url.port),
                        )

                        metrics = run_eval_few_shot_gsm8k(args)
                        self.assertGreaterEqual(
                            metrics["accuracy"],
                            TEST_MODEL_MATRIX[model]["accuracy"],
                        )
                finally:
                    kill_process_tree(process.pid)


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