import os

import pytest
from botocore.stub import Stubber

from twitch_airflow_components.hooks.metrics import Dimension, Metric, MetricsHook, _metric_to_dict


def test_dict_conversion():
    d1 = Dimension(Name="test-dim-1", Value="v1")
    d2 = Dimension(Name="test-dim-2", Value="v2")
    m = Metric(MetricName="test-metric", Value=0.456, Dimensions=[d1, d2])
    result = _metric_to_dict(m)
    assert result == {
        "MetricName": "test-metric",
        "Value": 0.456,
        "Dimensions": [
            {"Name": "test-dim-1", "Value": "v1"},
            {"Name": "test-dim-2", "Value": "v2"},
        ],
        "Unit": "None",
    }

    m = Metric(
        MetricName="test-metric-2", Value=True, Dimensions=[d1, d2], Unit="Count"
    )
    result = _metric_to_dict(m)
    assert result == {
        "MetricName": "test-metric-2",
        "Value": 1.0,
        "Dimensions": [
            {"Name": "test-dim-1", "Value": "v1"},
            {"Name": "test-dim-2", "Value": "v2"},
        ],
        "Unit": "Count",
    }

    m = Metric(MetricName="test-metric-3", Value=3, Dimensions=[d1, d2])
    result = _metric_to_dict(m)
    assert result == {
        "MetricName": "test-metric-3",
        "Value": 3.0,
        "Dimensions": [
            {"Name": "test-dim-1", "Value": "v1"},
            {"Name": "test-dim-2", "Value": "v2"},
        ],
        "Unit": "None",
    }


def test_init():
    hook = MetricsHook()  # Should not error.
    assert hook.default_namespace is None
    hook = MetricsHook(default_namespace="TestNamespace")
    assert hook.default_namespace == "TestNamespace"


def test_put_metric():
    hook = MetricsHook(default_namespace="TestNamespace")
    d1 = Dimension(Name="test-dim-1", Value="v1")
    d2 = Dimension(Name="test-dim-2", Value="v2")
    m1 = Metric(MetricName="test-metric", Value=0.456, Dimensions=[d1, d2])
    m2 = Metric(MetricName="test-metric-2", Value=1.456, Dimensions=[d1, d2])
    os.environ["AWS_DEFAULT_REGION"] = "us-west-2"
    stubber = Stubber(hook.conn)
    stubber.add_response(
        "put_metric_data",
        {"ResponseMetadata": {"HTTPStatusCode": 200}},
        {
            "MetricData": [
                {
                    "MetricName": "test-metric",
                    "Value": 0.456,
                    "Dimensions": [
                        {"Name": "test-dim-1", "Value": "v1"},
                        {"Name": "test-dim-2", "Value": "v2"},
                    ],
                    "Unit": "None",
                }
            ],
            "Namespace": "TestNamespace",
        },
    )
    stubber.add_response(
        "put_metric_data",
        {"ResponseMetadata": {"HTTPStatusCode": 500}},
        {
            "MetricData": [
                {
                    "MetricName": "test-metric-2",
                    "Value": 1.456,
                    "Dimensions": [
                        {"Name": "test-dim-1", "Value": "v1"},
                        {"Name": "test-dim-2", "Value": "v2"},
                    ],
                    "Unit": "None",
                }
            ],
            "Namespace": "TestNamespace",
        },
    )
    stubber.add_response(
        "put_metric_data",
        {"ResponseMetadata": {"HTTPStatusCode": 200}},
        {
            "MetricData": [
                {
                    "MetricName": "test-metric-2",
                    "Value": 1.456,
                    "Dimensions": [
                        {"Name": "test-dim-1", "Value": "v1"},
                        {"Name": "test-dim-2", "Value": "v2"},
                    ],
                    "Unit": "None",
                }
            ],
            "Namespace": "SomeNamespace",
        },
    )
    stubber.add_client_error("put_metric_data")
    stubber.activate()
    hook.put_metrics([m1])
    with pytest.raises(RuntimeError):
        hook.put_metrics([m2])
    hook.default_namespace = None
    hook.put_metrics([m2], namespace="SomeNamespace")
    with pytest.raises(ValueError):
        hook.put_metrics([m2])
