# Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
# SPDX-License-Identifier: Apache-2.0
import json
from datetime import datetime, time
from os import environ
from unittest.mock import MagicMock, patch
from zoneinfo import ZoneInfo

from freezegun import freeze_time

from instance_scheduler.configuration.instance_schedule import InstanceSchedule
from instance_scheduler.configuration.running_period import RunningPeriod
from instance_scheduler.configuration.running_period_dict_element import (
    RunningPeriodDictElement,
)
from instance_scheduler.configuration.scheduler_config import GlobalConfig
from instance_scheduler.handler.collect_configuration_description import (
    CollectConfigurationDescription,
    CollectConfigurationMetricsRequest,
)
from instance_scheduler.util.app_env import AppEnv
from tests.context import MockLambdaContext
from tests.integration.ops_metrics.conftest import solution_metrics_uuid

mockEvent: CollectConfigurationMetricsRequest = {
    "scheduled_action": "collect_configuration_metrics",
}

periods: list[RunningPeriodDictElement] = [
    RunningPeriodDictElement(
        period=RunningPeriod(
            name="test-period",
            begintime=time(10, 0, 0),
            endtime=time(20, 0, 0),
        )
    )
]

global_config = GlobalConfig(
    scheduled_services=["ec2"],
    schedule_clusters=False,
    tag_name="Schedule",
    regions=[],
    default_timezone=ZoneInfo("Asia/Hong_Kong"),
    schedules={
        "all-flags": InstanceSchedule(
            name="all-flags",
            periods=periods,
            override_status="running",
            use_metrics=True,
            stop_new_instances=True,
            use_maintenance_window=True,
            enforced=True,
            hibernate=True,
            retain_running=True,
            timezone="Asia/Hong_Kong",
        ),
        "no-flags-cfn": InstanceSchedule(
            name="no-flags-cfn",
            periods=periods,
            configured_in_stack="some-stack-arn",
            timezone="UTC",
        ),
        "non-default-tz-cfn": InstanceSchedule(
            name="non-default-tz-cfn",
            periods=periods,
            configured_in_stack="some-stack-arn",
            timezone="UTC",
        ),
        "explicit-tz-matches-default": InstanceSchedule(
            name="explicit-tz-matches-default",
            periods=periods,
            timezone="Asia/Hong_Kong",  # should not be counted by tz metric
        ),
    },
    trace=False,
    enable_ssm_maintenance_windows=True,
    use_metrics=True,
    schedule_lambda_account=True,
    create_rds_snapshot=False,
    started_tags="non-null tag",
    stopped_tags="",
    scheduler_role_name="Scheduler-Role",
    namespace="dev",
    organization_id="",
    aws_partition="aws",
    remote_account_ids=[],
)

env = {
    "START_TAGS": "non-null tag",
    "STOP_TAGS": "",
    "SCHEDULER_FREQUENCY": "10",
    "ENABLE_AWS_ORGANIZATIONS": "False",
    "ENABLE_EC2_SSM_MAINTENANCE_WINDOWS": "True",
}


@patch.dict(environ, env)
@freeze_time(datetime(2023, 6, 12, 12, 0, 0, tzinfo=ZoneInfo("UTC")))
def test_collect_configuration_description_metrics_collects_expected_metric(
    mock_metrics_endpoint: MagicMock, app_env: AppEnv
) -> None:
    with patch(
        "instance_scheduler.configuration.get_global_configuration"
    ) as global_config_access_point:
        global_config_access_point.return_value = global_config
        handler = CollectConfigurationDescription(mockEvent, MockLambdaContext())
        handler.handle_request()

        expected_metric = {
            "TimeStamp": "2023-06-12 12:00:00",
            "UUID": str(solution_metrics_uuid),
            "Solution": app_env.solution_id,
            "Version": app_env.solution_version,
            "Event_Name": "configuration_description",
            "Context": {
                "num_schedules": 4,
                "num_cfn_schedules": 2,
                "default_timezone": "Asia/Hong_Kong",
                "schedule_aurora_clusters": False,
                "create_rds_snapshots": False,
                "schedule_interval_minutes": 10,
                "memory_size_mb": 128,  # memory size from MockLambdaContext
                "using_organizations": False,
                "enable_ec2_ssm_maintenance_windows": True,
                "num_started_tags": 1,
                "num_stopped_tags": 0,
                "schedule_flag_counts": {
                    "stop_new_instances": 1,
                    "enforced": 1,
                    "retain_running": 1,
                    "hibernate": 1,
                    "override": 1,
                    "use_ssm_maintenance_window": 1,
                    "use_metrics": 1,
                    "non_default_timezone": 2,
                },
            },
        }

        assert mock_metrics_endpoint.call_count == 1
        json_payload = mock_metrics_endpoint.call_args[1]["data"]
        assert json.loads(json_payload) == expected_metric