# Copyright (c) 2026 Project CHIP Authors
#
# 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 dataclasses
import logging
import threading

from chiptest.log_config import LogMessageCounter
from chiptest.results import RunSummary

log = logging.getLogger(__name__)


@dataclasses.dataclass(eq=False)
class PeriodicStatusThread(threading.Thread):
    """
    Thread that periodically prints the status of test execution.

    Periodicity is defined as a number of log messages printed between status updates.
    """

    run_summary: RunSummary
    log_counter: LogMessageCounter
    periodicity: int

    def __post_init__(self) -> None:
        super().__init__(name="Status", daemon=True)

    def run(self) -> None:
        if self.periodicity == 0:
            log.debug("Periodic status overview is disabled")
            return

        log.debug("Starting periodic status overview thread with periodicity of %i log lines", self.periodicity)
        with self.log_counter.register_user() as log_counter:
            target_count = log_counter.total
            while not log_counter.cancelled:
                target_count += self.periodicity
                log_counter.wait_for_count_or_cancel(target_count)
                # We want to print the status one more time after cancellation to show the final result before termination.

                with self.run_summary:
                    current_iteration = self.run_summary.current_iteration
                    iterations = self.run_summary.iterations
                    successful_tests = self.run_summary.passed
                    failed_tests = self.run_summary.failed
                    expected_test_count = self.run_summary.expected_test_count

                test_status: list[str] = []
                if successful_tests > 0:
                    test_status.append(f"{successful_tests} successful")
                if failed_tests > 0:
                    test_status.append(f"{failed_tests} failed")
                if not test_status:
                    test_status.append("no tests completed")

                status_message = (
                    f"Iteration {current_iteration}/{iterations}: "
                    f"{successful_tests + failed_tests}/{expected_test_count} tests ({', '.join(test_status)})"
                )
                log.info("", extra={"status": status_message, "count": False})

        log.debug("Status overview thread has stopped")
