import datetime

from werkzeug.test import EnvironBuilder
from werkzeug.wrappers import Request

from rhdllib.auth import FlaskHmacSignature, HmacSignature


def create_test_request(method="GET", data=None, headers=None, args=None, path="/"):
    builder = EnvironBuilder(
        method=method, data=data, headers=headers, query_string=args, path=path
    )
    env = builder.get_environ()
    request = Request(env)
    return request


def test_aws_hmac_signature_is_valid():
    string_now = "20240919T132539Z"
    test_request = create_test_request(
        method="GET",
        path="/api/v1/jobs",
        headers={
            "User-Agent": "python-requests/2.27.1",
            "Accept-Encoding": "gzip, deflate",
            "Accept": "*/*",
            "Connection": "keep-alive",
            "Host": "127.0.0.1:5000",
            "X-Amz-Date": string_now,
            "Authorization": "AWS4-HMAC-SHA256 Credential=remoteci/5bb5c0ed-78f6-4e99-aa02-918c4677a97f/20240919/BHS3/api/aws4_request, SignedHeaders=host;x-amz-date, Signature=1bd13140ef20b04b1cbf73b4fa3cc92d3ca8322e91cea281b44a062b1884eb6f",
        },
    )
    now = datetime.datetime.strptime(string_now, "%Y%m%dT%H%M%SZ")
    options = {
        "service_name": "api",
        "service_key": "aws4_request",
        "region_name": "BHS3",
        "algorithm": "AWS4-HMAC-SHA256",
    }
    signature = FlaskHmacSignature(options, now).add_request(test_request)
    assert signature.access_key == "remoteci/5bb5c0ed-78f6-4e99-aa02-918c4677a97f"
    assert signature.is_valid(
        secret_key="9i9U20riVIBhTeCcXzhyqcVJHHIbWY4veo2Bfdn14NgvCaKw2JJYTm0tIHpGyk8w"
    )


def test_aws_hmac_signature_is_expired():
    twenty_min_before_now = "20240919T132539Z"
    test_request = create_test_request(
        method="GET",
        path="/api/v1/jobs",
        headers={
            "User-Agent": "python-requests/2.27.1",
            "Accept-Encoding": "gzip, deflate",
            "Accept": "*/*",
            "Connection": "keep-alive",
            "Host": "127.0.0.1:5000",
            "X-Amz-Date": twenty_min_before_now,
            "Authorization": "AWS4-HMAC-SHA256 Credential=remoteci/5bb5c0ed-78f6-4e99-aa02-918c4677a97f/20240919/BHS3/api/aws4_request, SignedHeaders=host;x-amz-date, Signature=1bd13140ef20b04b1cbf73b4fa3cc92d3ca8322e91cea281b44a062b1884eb6f",
        },
    )
    now = datetime.datetime.strptime("20240919T134539Z", "%Y%m%dT%H%M%SZ")
    options = {
        "service_name": "api",
        "service_key": "aws4_request",
        "region_name": "BHS3",
        "algorithm": "AWS4-HMAC-SHA256",
    }
    signature = FlaskHmacSignature(options, now).add_request(test_request)
    assert (
        signature.is_valid(
            "9i9U20riVIBhTeCcXzhyqcVJHHIbWY4veo2Bfdn14NgvCaKw2JJYTm0tIHpGyk8w"
        )
        is False
    )
    assert signature.error_message == "signature is expired"


def test_signature_invalid_if_request_tempered():
    string_now = "20240919T132539Z"
    test_request = create_test_request(
        method="GET",
        path="/api/v1/admin",
        headers={
            "User-Agent": "python-requests/2.27.1",
            "Accept-Encoding": "gzip, deflate",
            "Accept": "*/*",
            "Connection": "keep-alive",
            "Host": "127.0.0.1:5000",
            "X-Amz-Date": string_now,
            "Authorization": "AWS4-HMAC-SHA256 Credential=remoteci/5bb5c0ed-78f6-4e99-aa02-918c4677a97f/20240919/BHS3/api/aws4_request, SignedHeaders=host;x-amz-date, Signature=1bd13140ef20b04b1cbf73b4fa3cc92d3ca8322e91cea281b44a062b1884eb6f",
        },
    )
    now = datetime.datetime.strptime(string_now, "%Y%m%dT%H%M%SZ")
    options = {
        "service_name": "api",
        "service_key": "aws4_request",
        "region_name": "BHS3",
        "algorithm": "AWS4-HMAC-SHA256",
    }
    signature = FlaskHmacSignature(options, now).add_request(test_request)
    assert (
        signature.is_valid(
            "9i9U20riVIBhTeCcXzhyqcVJHHIbWY4veo2Bfdn14NgvCaKw2JJYTm0tIHpGyk8w"
        )
        is False
    )
    assert signature.error_message == "signature invalid"


def test_generate_headers():
    string_now = "20240919T132539Z"
    now = datetime.datetime.strptime(string_now, "%Y%m%dT%H%M%SZ")
    options = {
        "service_name": "api",
        "service_key": "aws4_request",
        "region_name": "BHS3",
        "algorithm": "AWS4-HMAC-SHA256",
    }
    request = {
        "method": "GET",
        "params": {},
        "data": "",
        "host": "127.0.0.1:5000",
        "path": "/api/v1/jobs",
    }
    signature = HmacSignature(options, now).add_request(request)
    credentials = {
        "access_key": "remoteci/5bb5c0ed-78f6-4e99-aa02-918c4677a97f",
        "secret_key": "9i9U20riVIBhTeCcXzhyqcVJHHIbWY4veo2Bfdn14NgvCaKw2JJYTm0tIHpGyk8w",
    }
    assert signature.generate_headers(credentials) == {
        "Host": "127.0.0.1:5000",
        "X-Amz-Date": string_now,
        "Authorization": "AWS4-HMAC-SHA256 Credential=remoteci/5bb5c0ed-78f6-4e99-aa02-918c4677a97f/20240919/BHS3/api/aws4_request, SignedHeaders=host;x-amz-date, Signature=1bd13140ef20b04b1cbf73b4fa3cc92d3ca8322e91cea281b44a062b1884eb6f",
    }
