import pytest

from .client import (
    GlueAthenaClient,
    _format_table_description,
    _iter_table_columns,
    _parse_column,
    _parse_table,
    _s3_to_http,
    _table_type,
)


@pytest.mark.parametrize(
    ("url", "expected"),
    [
        ("https://example.com/path", "https://example.com/path"),
        (
            "s3://my-bucket/path/to/object.csv",
            "https://s3.console.aws.amazon.com/s3/buckets/"
            "my-bucket/?prefix=path/to/object.csv",
        ),
        (
            "s3://my-bucket",
            "https://s3.console.aws.amazon.com/s3/buckets/my-bucket/?prefix=",
        ),
        (
            "s3://my-bucket/folder/",
            "https://s3.console.aws.amazon.com/s3/buckets/"
            "my-bucket/?prefix=folder/",
        ),
    ],
)
def test__s3_to_http(url: str, expected: str):
    assert _s3_to_http(url) == expected


def test__format_table_description_without_description():
    location = "s3://bucket/folder/"
    expected = (
        "Bucket location: [s3://bucket/folder/]"
        "(https://s3.console.aws.amazon.com/s3/buckets/"
        "bucket/?prefix=folder/)"
    )
    assert _format_table_description(location, None) == expected


def test__format_table_description_with_description():
    location = "s3://bucket/folder/"
    description = "Table description"
    expected = (
        "Table description\n"
        "Bucket location: [s3://bucket/folder/]"
        "(https://s3.console.aws.amazon.com/s3/buckets/"
        "bucket/?prefix=folder/)"
    )
    assert _format_table_description(location, description) == expected


def test__format_table_description_empty_location_without_description():
    assert _format_table_description("", None) is None


def test__format_table_description_empty_location_with_description():
    assert (
        _format_table_description("", "Table description")
        == "Table description"
    )


def test__table_type():
    assert _table_type(None) == "TABLE"
    assert _table_type("EXTERNAL_TABLE") == "EXTERNAL"
    assert _table_type("VIRTUAL_VIEW") == "VIEW"
    assert _table_type("random") == "TABLE"


def test__parse_column_missing_name():
    assert _parse_column("table_arn", {}, 0) is None


def test__parse_column_with_name():
    raw = {"Name": "col_a", "Type": "varchar", "Comment": "desc"}
    parsed = _parse_column("table_arn", raw, 2)
    assert parsed == {
        "column_id": "table_arn.col_a",
        "column_name": "col_a",
        "data_type": "varchar",
        "description": "desc",
        "ordinal_position": 2,
        "table_id": "table_arn",
        "tags": [],
    }


def test__resource_arn():
    client = GlueAthenaClient.__new__(GlueAthenaClient)
    client._region = "eu-west-1"
    client._account_id = "123"

    assert client._resource_arn("database", "db1") == (
        "arn:aws:glue:eu-west-1:123:database/db1"
    )
    assert client._resource_arn("table", "db1/table1") == (
        "arn:aws:glue:eu-west-1:123:table/db1/table1"
    )


def test_databases_is_hard_coded_catalog():
    client = GlueAthenaClient.__new__(GlueAthenaClient)
    assert client.databases() == [
        {"database_id": "awsdatacatalog", "database_name": "awsdatacatalog"}
    ]


def test__parse_table():
    raw_table = {
        "Name": "orders",
        "Description": "Orders table",
        "TableType": "EXTERNAL_TABLE",
        "StorageDescriptor": {"Location": "s3://bucket/orders/"},
    }

    parsed = _parse_table(raw_table, "schema-id", "table-arn")
    assert parsed == {
        "table_id": "table-arn",
        "schema_id": "schema-id",
        "table_name": "orders",
        "description": (
            "Orders table\n"
            "Bucket location: [s3://bucket/orders/]"
            "(https://s3.console.aws.amazon.com/s3/buckets/"
            "bucket/?prefix=orders/)"
        ),
        "tags": [],
        "type": "EXTERNAL",
    }


def test__iter_table_columns_keeps_order_and_skips_duplicates():
    raw_table = {
        "StorageDescriptor": {
            "Columns": [
                {"Name": "id", "Type": "int"},
                {"Name": "ds", "Type": "string"},
            ]
        },
        "PartitionKeys": [
            {"Name": "ds", "Type": "string"},
            {"Name": "country", "Type": "varchar"},
        ],
    }

    parsed = _iter_table_columns(raw_table, "table-arn")
    assert [column["column_name"] for column in parsed] == [
        "id",
        "ds",
        "country",
    ]
    assert [column["ordinal_position"] for column in parsed] == [0, 1, 2]
