from pokie.codegen.pg import PgTableSpec


class TestPgSpec:
    tablespec_fieldnames = {
        "id_tablespec": {
            "pk": True,
            "auto": True,
            "nullable": False,
            "fk": False,
            "fk_table": None,
            "fk_schema": None,
            "fk_column": None,
            "dtype": "int4",
        },
        "field_bigint": {
            "pk": False,
            "auto": False,
            "nullable": True,
            "fk": False,
            "fk_table": None,
            "fk_schema": None,
            "fk_column": None,
            "dtype": "int8",
        },
        "field_bigserial": {
            "pk": False,
            "auto": True,
            "nullable": False,
            "fk": False,
            "fk_table": None,
            "fk_schema": None,
            "fk_column": None,
            "dtype": "int8",
        },
        "field_bit": {
            "pk": False,
            "auto": False,
            "nullable": True,
            "fk": False,
            "fk_table": None,
            "fk_schema": None,
            "fk_column": None,
            "dtype": "bit",
        },
        "field_varbit": {
            "pk": False,
            "auto": False,
            "nullable": True,
            "fk": False,
            "fk_table": None,
            "fk_schema": None,
            "fk_column": None,
            "dtype": "varbit",
        },
        "field_box": {
            "pk": False,
            "auto": False,
            "nullable": True,
            "fk": False,
            "fk_table": None,
            "fk_schema": None,
            "fk_column": None,
            "dtype": "box",
        },
        "field_bytea": {
            "pk": False,
            "auto": False,
            "nullable": True,
            "fk": False,
            "fk_table": None,
            "fk_schema": None,
            "fk_column": None,
            "dtype": "bytea",
        },
        "field_char": {
            "pk": False,
            "auto": False,
            "nullable": True,
            "fk": False,
            "fk_table": None,
            "fk_schema": None,
            "fk_column": None,
            "dtype": "bpchar",
        },
        "field_varchar": {
            "pk": False,
            "auto": False,
            "nullable": True,
            "fk": False,
            "fk_table": None,
            "fk_schema": None,
            "fk_column": None,
            "dtype": "varchar",
        },
        "field_cidr": {
            "pk": False,
            "auto": False,
            "nullable": True,
            "fk": False,
            "fk_table": None,
            "fk_schema": None,
            "fk_column": None,
            "dtype": "cidr",
        },
        "field_circle": {
            "pk": False,
            "auto": False,
            "nullable": True,
            "fk": False,
            "fk_table": None,
            "fk_schema": None,
            "fk_column": None,
            "dtype": "circle",
        },
        "field_date": {
            "pk": False,
            "auto": False,
            "nullable": True,
            "fk": False,
            "fk_table": None,
            "fk_schema": None,
            "fk_column": None,
            "dtype": "date",
        },
        "field_float8": {
            "pk": False,
            "auto": False,
            "nullable": True,
            "fk": False,
            "fk_table": None,
            "fk_schema": None,
            "fk_column": None,
            "dtype": "float8",
        },
        "field_inet": {
            "pk": False,
            "auto": False,
            "nullable": True,
            "fk": False,
            "fk_table": None,
            "fk_schema": None,
            "fk_column": None,
            "dtype": "inet",
        },
        "field_int4": {
            "pk": False,
            "auto": False,
            "nullable": True,
            "fk": False,
            "fk_table": None,
            "fk_schema": None,
            "fk_column": None,
            "dtype": "int4",
        },
        "field_interval": {
            "pk": False,
            "auto": False,
            "nullable": True,
            "fk": False,
            "fk_table": None,
            "fk_schema": None,
            "fk_column": None,
            "dtype": "interval",
        },
        "field_json": {
            "pk": False,
            "auto": False,
            "nullable": True,
            "fk": False,
            "fk_table": None,
            "fk_schema": None,
            "fk_column": None,
            "dtype": "json",
        },
        "field_jsonb": {
            "pk": False,
            "auto": False,
            "nullable": True,
            "fk": False,
            "fk_table": None,
            "fk_schema": None,
            "fk_column": None,
            "dtype": "jsonb",
        },
        "field_line": {
            "pk": False,
            "auto": False,
            "nullable": True,
            "fk": False,
            "fk_table": None,
            "fk_schema": None,
            "fk_column": None,
            "dtype": "line",
        },
        "field_lseg": {
            "pk": False,
            "auto": False,
            "nullable": True,
            "fk": False,
            "fk_table": None,
            "fk_schema": None,
            "fk_column": None,
            "dtype": "lseg",
        },
        "field_macaddr": {
            "pk": False,
            "auto": False,
            "nullable": True,
            "fk": False,
            "fk_table": None,
            "fk_schema": None,
            "fk_column": None,
            "dtype": "macaddr",
        },
        "field_macaddr8": {
            "pk": False,
            "auto": False,
            "nullable": True,
            "fk": False,
            "fk_table": None,
            "fk_schema": None,
            "fk_column": None,
            "dtype": "macaddr8",
        },
        "field_money": {
            "pk": False,
            "auto": False,
            "nullable": True,
            "fk": False,
            "fk_table": None,
            "fk_schema": None,
            "fk_column": None,
            "dtype": "money",
        },
        "field_numeric": {
            "pk": False,
            "auto": False,
            "nullable": True,
            "fk": False,
            "fk_table": None,
            "fk_schema": None,
            "fk_column": None,
            "dtype": "numeric",
        },
        "field_path": {
            "pk": False,
            "auto": False,
            "nullable": True,
            "fk": False,
            "fk_table": None,
            "fk_schema": None,
            "fk_column": None,
            "dtype": "path",
        },
        "field_point": {
            "pk": False,
            "auto": False,
            "nullable": True,
            "fk": False,
            "fk_table": None,
            "fk_schema": None,
            "fk_column": None,
            "dtype": "point",
        },
        "field_polygon": {
            "pk": False,
            "auto": False,
            "nullable": True,
            "fk": False,
            "fk_table": None,
            "fk_schema": None,
            "fk_column": None,
            "dtype": "polygon",
        },
        "field_float4": {
            "pk": False,
            "auto": False,
            "nullable": True,
            "fk": False,
            "fk_table": None,
            "fk_schema": None,
            "fk_column": None,
            "dtype": "float4",
        },
        "field_int2": {
            "pk": False,
            "auto": False,
            "nullable": True,
            "fk": False,
            "fk_table": None,
            "fk_schema": None,
            "fk_column": None,
            "dtype": "int2",
        },
        "field_smallserial": {
            "pk": False,
            "auto": True,
            "nullable": False,
            "fk": False,
            "fk_table": None,
            "fk_schema": None,
            "fk_column": None,
            "dtype": "smallserial",
        },
        "field_text": {
            "pk": False,
            "auto": False,
            "nullable": True,
            "fk": False,
            "fk_table": None,
            "fk_schema": None,
            "fk_column": None,
            "dtype": "text",
        },
        "field_time": {
            "pk": False,
            "auto": False,
            "nullable": True,
            "fk": False,
            "fk_table": None,
            "fk_schema": None,
            "fk_column": None,
            "dtype": "time",
        },
        "field_timetz": {
            "pk": False,
            "auto": False,
            "nullable": True,
            "fk": False,
            "fk_table": None,
            "fk_schema": None,
            "fk_column": None,
            "dtype": "timetz",
        },
        "field_timestamp": {
            "pk": False,
            "auto": False,
            "nullable": True,
            "fk": False,
            "fk_table": None,
            "fk_schema": None,
            "fk_column": None,
            "dtype": "timestamp",
        },
        "field_timestamptz": {
            "pk": False,
            "auto": False,
            "nullable": True,
            "fk": False,
            "fk_table": None,
            "fk_schema": None,
            "fk_column": None,
            "dtype": "timestamptz",
        },
        "field_tsquery": {
            "pk": False,
            "auto": False,
            "nullable": True,
            "fk": False,
            "fk_table": None,
            "fk_schema": None,
            "fk_column": None,
            "dtype": "tsquery",
        },
        "field_tsvector": {
            "pk": False,
            "auto": False,
            "nullable": True,
            "fk": False,
            "fk_table": None,
            "fk_schema": None,
            "fk_column": None,
            "dtype": "tsvector",
        },
        "field_uuid": {
            "pk": False,
            "auto": False,
            "nullable": True,
            "fk": False,
            "fk_table": None,
            "fk_schema": None,
            "fk_column": None,
            "dtype": "uuid",
        },
        "field_xml": {
            "pk": False,
            "auto": False,
            "nullable": True,
            "fk": False,
            "fk_table": None,
            "fk_schema": None,
            "fk_column": None,
            "dtype": "xml",
        },
    }
    tablespec_rel_fieldnames = {
        "id_tablespec_rel": {
            "pk": True,
            "auto": True,
            "nullable": False,
            "fk": False,
            "fk_table": None,
            "fk_schema": None,
            "fk_column": None,
            "dtype": "int4",
        },
        "fk_tablespec_serial": {
            "pk": False,
            "auto": False,
            "nullable": False,
            "fk": True,
            "fk_table": "tablespec_serial",
            "fk_schema": "public",
            "fk_column": "id_tablespec",
            "dtype": "int4",
        },
    }

    def test_tablespec(self, pokie_db):
        generator = PgTableSpec(pokie_db)
        spec = generator.generate("tablespec_serial")
        assert spec.table == "tablespec_serial"
        assert spec.schema == "public"
        assert spec.pk == "id_tablespec"
        assert len(spec.fields) == len(self.tablespec_fieldnames)
        for field in spec.fields:
            assert field.name in self.tablespec_fieldnames.keys()
            field_spec = self.tablespec_fieldnames[field.name]
            assert field.pk == field_spec["pk"]
            assert field.auto == field_spec["auto"]
            assert field.nullable == field_spec["nullable"]
            assert field.fk == field_spec["fk"]
            assert field.fk_table == field_spec["fk_table"]
            assert field.fk_schema == field_spec["fk_schema"]
            assert field.fk_column == field_spec["fk_column"]

    def test_tablespec_rel(self, pokie_db):
        generator = PgTableSpec(pokie_db)
        spec = generator.generate("tablespec_rel")
        assert spec.table == "tablespec_rel"
        assert spec.schema == "public"
        assert spec.pk == "id_tablespec_rel"
        assert len(spec.fields) == len(self.tablespec_rel_fieldnames)
        for field in spec.fields:
            assert field.name in self.tablespec_rel_fieldnames.keys()
            field_spec = self.tablespec_rel_fieldnames[field.name]
            assert field.pk == field_spec["pk"]
            assert field.auto == field_spec["auto"]
            assert field.nullable == field_spec["nullable"]
            assert field.fk == field_spec["fk"]
            assert field.fk_table == field_spec["fk_table"]
            assert field.fk_schema == field_spec["fk_schema"]
            assert field.fk_column == field_spec["fk_column"]
