# Licensed to the Apache Software Foundation (ASF) under one
# or more contributor license agreements.  See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership.  The ASF licenses this file
# to you 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.
from __future__ import annotations

from unittest import mock

import pytest
from pendulum import DateTime
from pendulum.tz.timezone import Timezone

from airflow.api_connexion.exceptions import BadRequest
from airflow.api_connexion.parameters import (
    check_limit,
    format_datetime,
    format_parameters,
    validate_istimezone,
)
from airflow.utils import timezone
from tests.test_utils.config import conf_vars


class TestValidateIsTimezone:
    def setup_method(self) -> None:
        from datetime import datetime

        self.naive = datetime.now()
        self.timezoned = datetime.now(tz=timezone.utc)

    def test_gives_400_for_naive(self):
        with pytest.raises(BadRequest):
            validate_istimezone(self.naive)

    def test_timezone_passes(self):
        assert validate_istimezone(self.timezoned) is None


class TestDateTimeParser:
    def setup_method(self) -> None:
        self.default_time = "2020-06-13T22:44:00+00:00"
        self.default_time_2 = "2020-06-13T22:44:00Z"

    def test_works_with_datestring_ending_00_00(self):
        datetime = format_datetime(self.default_time)
        datetime2 = timezone.parse(self.default_time)
        assert datetime == datetime2
        assert datetime.isoformat() == self.default_time

    def test_works_with_datestring_ending_with_zed(self):
        datetime = format_datetime(self.default_time_2)
        datetime2 = timezone.parse(self.default_time_2)
        assert datetime == datetime2
        assert datetime.isoformat() == self.default_time  # python uses +00:00 instead of Z

    def test_raises_400_for_invalid_arg(self):
        invalid_datetime = "2020-06-13T22:44:00P"
        with pytest.raises(BadRequest):
            format_datetime(invalid_datetime)


class TestMaximumPagelimit:
    @conf_vars({("api", "maximum_page_limit"): "320"})
    def test_maximum_limit_return_val(self):
        limit = check_limit(300)
        assert limit == 300

    @conf_vars({("api", "maximum_page_limit"): "320"})
    def test_maximum_limit_returns_configured_if_limit_above_conf(self):
        limit = check_limit(350)
        assert limit == 320

    @conf_vars({("api", "maximum_page_limit"): "1000"})
    def test_limit_returns_set_max_if_give_limit_is_exceeded(self):
        limit = check_limit(1500)
        assert limit == 1000

    @conf_vars({("api", "fallback_page_limit"): "100"})
    def test_limit_of_zero_returns_default(self):
        limit = check_limit(0)
        assert limit == 100

    @conf_vars({("api", "maximum_page_limit"): "1500"})
    def test_negative_limit_raises(self):
        with pytest.raises(BadRequest):
            check_limit(-1)


class TestFormatParameters:
    def test_should_works_with_datetime_formatter(self):
        decorator = format_parameters({"param_a": format_datetime})
        endpoint = mock.MagicMock()
        decorated_endpoint = decorator(endpoint)

        decorated_endpoint(param_a="2020-01-01T0:0:00+00:00")

        endpoint.assert_called_once_with(param_a=DateTime(2020, 1, 1, 0, tzinfo=Timezone("UTC")))

    def test_should_propagate_exceptions(self):
        decorator = format_parameters({"param_a": format_datetime})
        endpoint = mock.MagicMock()
        decorated_endpoint = decorator(endpoint)
        with pytest.raises(BadRequest):
            decorated_endpoint(param_a="XXXXX")

    @conf_vars({("api", "maximum_page_limit"): "100"})
    def test_should_work_with_limit(self):
        decorator = format_parameters({"limit": check_limit})
        endpoint = mock.MagicMock()
        decorated_endpoint = decorator(endpoint)
        decorated_endpoint(limit=89)
        endpoint.assert_called_once_with(limit=89)
