"""Module for normalize endpoint response schema."""
from enum import Enum
from typing import List, Optional, Dict, Any, Type, Union
from datetime import datetime

from pydantic import BaseModel
from pydantic.types import StrictStr
from ga4gh.vrsatile.pydantic.vrsatile_models import VariationDescriptor, \
    CanonicalVariation, ComplexVariation


class HGVSDupDelMode(str, Enum):
    """Define options for HGVSDupDelMode.
    This mode determines how to interpret HGVS dup/del.
    """

    DEFAULT = "default"
    CNV = "cnv"
    REPEATED_SEQ_EXPR = "repeated_seq_expr"
    LITERAL_SEQ_EXPR = "literal_seq_expr"


class ServiceMeta(BaseModel):
    """Metadata regarding the variation-normalization service."""

    name = "variation-normalizer"
    version: StrictStr
    response_datetime: datetime
    url = "https://github.com/cancervariants/variation-normalization"

    class Config:
        """Configure schema example."""

        @staticmethod
        def schema_extra(schema: Dict[str, Any],
                         model: Type["ServiceMeta"]) -> None:
            """Configure OpenAPI schema"""
            if "title" in schema.keys():
                schema.pop("title", None)
            for prop in schema.get("properties", {}).values():
                prop.pop("title", None)
            schema["example"] = {
                "name": "variation-normalizer",
                "version": "0.1.0",
                "response_datetime": "2021-04-05T16:44:15.367831",
                "url": "https://github.com/cancervariants/variation-normalization"  # noqa: E501
            }


class ServiceResponse(BaseModel):
    """Base response model for services"""

    warnings: Optional[List[StrictStr]]
    service_meta_: ServiceMeta


class NormalizeService(ServiceResponse):
    """A response to normalizing a variation to a single GA4GH Value Object Descriptor."""  # noqa: E501

    variation_query: StrictStr
    variation_descriptor: Optional[VariationDescriptor]

    class Config:
        """Configure model."""

        @staticmethod
        def schema_extra(schema: Dict[str, Any],
                         model: Type["NormalizeService"]) -> None:
            """Configure OpenAPI schema."""
            if "title" in schema.keys():
                schema.pop("title", None)
            for prop in schema.get("properties", {}).values():
                prop.pop("title", None)
            schema["example"] = {
                "variation_query": "BRAF V600E",
                "variation_descriptor": {
                    "id": "normalize.variation:BRAF%20V600E",
                    "label": "BRAF V600E",
                    "type": "VariationDescriptor",
                    "variation_id": "ga4gh:VA.8JkgnqIgYqufNl-OV_hpRG_aWF9UFQCE",  # noqa: E501
                    "variation": {
                        "_id": "ga4gh:VA.8JkgnqIgYqufNl-OV_hpRG_aWF9UFQCE",
                        "location": {
                            "_id": "ga4gh:VSL.AqrQ-EkAvTrXOFn70_8i3dXF5shBBZ5i",  # noqa: E501
                            "interval": {
                                "end": {"value": 640, "type": "Number"},
                                "start": {"value": 639, "type": "Number"},
                                "type": "SequenceInterval"
                            },
                            "sequence_id": "ga4gh:SQ.WaAJ_cXXn9YpMNfhcq9lnzIvaB9ALawo",  # noqa: E501
                            "type": "SequenceLocation"
                        },
                        "state": {
                            "sequence": "E",
                            "type": "LiteralSequenceExpression"
                        },
                        "type": "Allele"
                    },
                    "molecule_context": "protein",
                    "structural_type": "SO:0001606",
                    "vrs_ref_allele_seq": "V",
                    "gene_context": {
                        "id": "normalize.gene:BRAF",
                        "type": "GeneDescriptor",
                        "label": "BRAF",
                        "gene_id": "hgnc:1097",
                        "xrefs": [
                            "ncbigene:673",
                            "ensembl:ENSG00000157764"
                        ],
                        "alternate_labels": [
                            "B-Raf proto-oncogene, serine/threonine kinase",
                            "BRAF1"
                        ],
                        "extensions": [
                            {
                                "name": "symbol_status",
                                "value": "approved",
                                "type": "Extension"
                            },
                            {
                                "name": "associated_with",
                                "value": [
                                    "vega:OTTHUMG00000157457",
                                    "ucsc:uc003vwc.5",
                                    "ccds:CCDS5863",
                                    "ccds:CCDS87555",
                                    "uniprot:P15056",
                                    "pubmed:2284096",
                                    "pubmed:1565476",
                                    "cosmic:BRAF",
                                    "omim:164757",
                                    "orphanet:119066",
                                    "iuphar:1943",
                                    "ena.embl:M95712",
                                    "refseq:NM_004333"
                                ],
                                "type": "Extension"
                            },
                            {
                                "name": "chromosome_location",
                                "value": {
                                    "_id": "ga4gh:VCL.O6yCQ1cnThOrTfK9YUgMlTfM6HTqbrKw",  # noqa: E501
                                    "type": "ChromosomeLocation",
                                    "species_id": "taxonomy:9606",
                                    "chr": "7",
                                    "interval": {
                                        "end": "q34",
                                        "start": "q34",
                                        "type": "CytobandInterval"
                                    }
                                },
                                "type": "Extension"
                            }
                        ]
                    }
                },
                "service_meta_": {
                    "name": "variation-normalizer",
                    "version": "0.2.17",
                    "response_datetime": "2022-01-26T22:23:41.821673",
                    "url": "https://github.com/cancervariants/variation-normalization"  # noqa: E501
                }
            }


class TranslateIdentifierService(ServiceResponse):
    """A response to translating identifiers."""

    identifier_query: StrictStr
    aliases: List[StrictStr]

    class Config:
        """Configure model."""

        @staticmethod
        def schema_extra(schema: Dict[str, Any],
                         model: Type["TranslateIdentifierService"]) -> None:
            """Configure OpenAPI schema."""
            if "title" in schema.keys():
                schema.pop("title", None)
            for prop in schema.get("properties", {}).values():
                prop.pop("title", None)
            schema["example"] = {
                "identifier_query": "NP_004324.2",
                "warnings": None,
                "aliases": [
                    "Ensembl:ENSP00000288602.6",
                    "ensembl:ENSP00000288602.6",
                    "Ensembl:ENSP00000493543.1",
                    "ensembl:ENSP00000493543.1",
                    "MD5:74c9b69323bd112084c1b5b385e7e6c5",
                    "NCBI:NP_004324.2",
                    "refseq:NP_004324.2",
                    "SEGUID:sfzILpNpX8UFB/vgH9LOKLpl/+g",
                    "SHA1:b1fcc82e93695fc50507fbe01fd2ce28ba65ffe8",
                    "VMC:GS_cQvw4UsHHRRlogxbWCB8W-mKD4AraM9y",
                    "sha512t24u:cQvw4UsHHRRlogxbWCB8W-mKD4AraM9y",
                    "ga4gh:SQ.cQvw4UsHHRRlogxbWCB8W-mKD4AraM9y"
                ],
                "service_meta_": {
                    "name": "variation-normalizer",
                    "version": "0.2.14",
                    "response_datetime": "2021-11-18T14:10:53.909158",
                    "url": "https://github.com/cancervariants/variation-normalization"  # noqa: E501
                }
            }


class CanonicalSPDIToCategoricalVariationService(ServiceResponse):
    """A response model for the canonical spdi to categorical variation service"""

    canonical_spdi_query: str
    categorical_variation: Optional[Union[CanonicalVariation, ComplexVariation]]

    class Config:
        """Configure model."""

        @staticmethod
        def schema_extra(
                schema: Dict[str, Any],
                model: Type["CanonicalSPDIToCategoricalVariationService"]) -> None:
            """Configure OpenAPI schema."""
            if "title" in schema.keys():
                schema.pop("title", None)
            for prop in schema.get("properties", {}).values():
                prop.pop("title", None)
            schema["example"] = {
                "canonical_spdi_query": "NC_000007.14:140753335:A:T",
                "warnings": [],
                "categorical_variation": {
                    "_id": "ga4gh:VCC.W0r_NF_ecKXjgvTwcMNkyVS1pB_CXMj9",
                    "type": "CanonicalVariation",
                    "complement": False,
                    "variation": {
                        "_id": "ga4gh:VA.fZiBjQEolbkL0AxjoTZf4SOkFy9J0ebU",
                        "type": "Allele",
                        "location": {
                            "_id": "ga4gh:VSL.zga82-TpYiNmBESCfvDvAz9DyvJF98I-",
                            "type": "SequenceLocation",
                            "sequence_id": "ga4gh:SQ.F-LrLMe1SRpfUZHkQmvkVKFEGaoDeHul",
                            "interval": {
                                "type": "SequenceInterval",
                                "start": {
                                    "type": "Number",
                                    "value": 140753335
                                },
                                "end": {
                                    "type": "Number",
                                    "value": 140753336
                                }
                            }
                        },
                        "state": {
                            "type": "LiteralSequenceExpression",
                            "sequence": "T"
                        }
                    }
                },
                "service_meta_": {
                    "version": "0.2.20",
                    "response_datetime": "2022-02-20T17:16:19.415675",
                    "name": "variation-normalizer",
                    "url": "https://github.com/cancervariants/variation-normalization"
                }
            }
