import copy
from unittest import mock
from urllib import parse as urlparse

import pytest

import tests.utils
from passerelle.contrib.tcl.models import Line, Stop, Tcl

LIGNE_BUS = {
    "values": [
        {
            "last_update_fme": "2017-06-27 06:01:10",
            "nom_trace": "Croix Rousse - Plateaux de St Rambert",
            "last_update": "None",
            "code_trace": "2Aa1",
            "gid": "1003",
            "ligne": "2",
            "sens": "Aller",
        },
    ]
}

LIGNE_TRAM = {
    "values": [
        {
            "ligne": "T2",
            "sens": "Retour",
            "libelle": "St Priest Bel Air - Perrache",
            "indice": "",
            "ut": "UTT",
            "couleur": "54 0 160",
            "infos": "",
            "gid": "4",
            "last_update_fme": "2017-06-27 06:01:10",
            "code_titan": "T2r2",
            "last_update": "None",
        },
    ]
}

LIGNE_MF = {
    "values": [
        {
            "last_update_fme": "2017-06-27 06:01:10",
            "ligne": "B",
            "ut": "UTMA",
            "indice": "",
            "couleur": "0 170 227",
            "libelle": "Charpennes - Oullins Gare",
            "last_update": "None",
            "gid": "17",
            "code_titan": "302Aa1",
            "infos": "",
            "sens": "Aller",
        },
    ]
}

ARRETS = {
    "type": "FeatureCollection",
    "features": [
        {
            "geometry": {"coordinates": [4.84756760746877, 45.7594333137236], "type": "Point"},
            "type": "Feature",
            "properties": {
                "pmr": "t",
                "id": "46026",
                "nom": "Place Guichard",
                "last_update_fme": "2017-07-10 06:00:28",
                "last_update": "",
                "gid": "92",
                "desserte": "302A:R",
                "ascenseur": "f",
                "escalator": "f",
            },
        },
    ],
}

PASSAGES = {
    "values": [
        {
            "last_update_fme": "2017-06-27 07:32:27",
            "coursetheorique": "302A-019AT:53:1:14",
            "ligne": "302A",
            "direction": "Gare d'Oullins",
            "gid": "12429",
            "idtarretdestination": "46035",
            "heurepassage": "2017-06-27 07:33:50",
            "delaipassage": "1 min",
            "id": "46026",
            "type": "E",
        },
        {
            "gid": "12430",
            "direction": "Gare d'Oullins",
            "idtarretdestination": "46035",
            "ligne": "302A",
            "last_update_fme": "2017-06-27 07:32:27",
            "coursetheorique": "302A-019AT:61:1:3",
            "id": "46026",
            "delaipassage": "4 min",
            "type": "E",
            "heurepassage": "2017-06-27 07:36:55",
        },
    ]
}


@pytest.fixture
def connector(db):
    return tests.utils.setup_access_rights(Tcl.objects.create(slug='test'))


def tcl_responses(url, **kwargs):
    content = {
        '/tcllignebus_2_0_0': LIGNE_BUS,
        '/tcllignemf_2_0_0': LIGNE_MF,
        '/tcllignetram_2_0_0': LIGNE_TRAM,
        '/geojson/tclarret': ARRETS,
        '/tclpassagearret': PASSAGES,
    }.get(urlparse.urlparse(url).path)
    return tests.utils.FakedResponse(json=lambda: copy.deepcopy(content), status_code=200)


@mock.patch('passerelle.utils.Request.get')
def test_cron(mocked_get, app, connector):
    mocked_get.side_effect = tcl_responses
    connector.daily()
    assert Line.objects.count() == 3
    assert Stop.objects.count() == 1

    metro = Line.objects.get(transport_key='tcllignemf')
    assert metro.ligne == 'B'
    assert metro.html_bg_color == '00aae3'
    assert metro.html_fg_color == '000000'
    assert metro.code_titan_short == '302A'

    assert Stop.objects.get(id_data='46026').pmr is True
    assert Stop.objects.get(id_data='46026').escalator is False
    assert Stop.objects.get(id_data='46026').ascenseur is False


@mock.patch('passerelle.utils.Request.get')
def test_stop_info(mocked_get, app, connector):
    mocked_get.side_effect = tcl_responses
    connector.daily()
    endpoint = tests.utils.generic_endpoint_url('tcl', 'stop', slug=connector.slug)
    assert endpoint == '/tcl/test/stop'
    resp = app.get(endpoint + '/46026')
    assert resp.json['data']['nom'] == 'Place Guichard'
    assert len(resp.json['data']['passings']) == 2
    assert resp.json['data']['passings'][0]['line_info']['ligne'] == 'B'
    assert resp.json['data']['passings_by_line'][0]['ligne'] == 'B'
    assert len(resp.json['data']['passings_by_line'][0]['passings']) == 2


@mock.patch('passerelle.utils.Request.get')
def test_availability(mocked_get, app, connector):
    mocked_get.side_effect = tcl_responses
    connector.check_status()
