# passerelle - uniform access to multiple data sources and services
# Copyright (C) 2018 Entr'ouvert
#
# This program is free software: you can redistribute it and/or modify it
# under the terms of the GNU Affero General Public License as published
# by the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program.  If not, see <http://www.gnu.org/licenses/>.

import csv
import functools
import io
import json
from urllib.parse import parse_qs

import httmock
import pytest
from django.db import connection
from django.db.migrations.executor import MigrationExecutor

import tests.utils
from passerelle.contrib.rsa13.models import DEFAULTS, RSA13Resource, dump_csv_columns

from .test_manager import login


@pytest.fixture
def rsa13(db):
    return tests.utils.make_resource(
        RSA13Resource,
        title='Test',
        slug='test',
        description='Test',
        webservice_base_url='https://rsa-cd13.com',
        basic_auth_username='username',
        basic_auth_password='password',
    )


@pytest.fixture
def url(rsa13):
    return '/rsa13/%s/' % rsa13.slug


def mock_response(*path_contents):
    def decorator(func):
        @httmock.urlmatch()
        def error(url, request):
            assert False, 'request to %s' % (url,)

        @functools.wraps(func)
        def wrapper(*args, **kwargs):
            handlers = []
            for row in path_contents:
                try:
                    path, query, content = row
                except ValueError:
                    path, content = row
                    query = None

                def make_handler(path, query, content):
                    @httmock.urlmatch(path=path)
                    def handler(url, request):
                        if query:
                            assert parse_qs(url.query) == parse_qs(query), 'query does not match'
                        return json.dumps(content)

                    return handler

                handlers.append(make_handler(path, query, content))
            handlers.append(error)

            with httmock.HTTMock(*handlers):
                return func(*args, **kwargs)

        return wrapper

    return decorator


@mock_response(['/api/check', {'ping': 'pong'}])
def test_check_status(rsa13):
    rsa13.check_status()


EMAIL = 'john.doe@example.com'
IP = '127.0.0.1'


@pytest.fixture
def app(app):
    '''Add authentication params email/ip to all requests'''
    orig_do_request = app.do_request

    def do_request(req, *args, **kwargs):
        qs = 'email=%s&ip=%s' % (EMAIL, IP)
        if req.environ['QUERY_STRING']:
            req.environ['QUERY_STRING'] += '&' + qs
        else:
            req.environ['QUERY_STRING'] = qs
        return orig_do_request(req, *args, **kwargs)

    app.do_request = do_request
    return app


MOTICLODAC_CODES = [
    {'id': 'ABSSUIVI', 'text': 'Aucune info. sur le suivi'},
    {'id': 'CADUQUE', 'text': 'Caduque'},
    {'id': 'REALISEE', 'text': 'Réalisée'},
    {'id': 'RUPTINJUST', 'text': 'Rupture injustifiée'},
    {'id': 'RUPTJUSTIF', 'text': 'Rupture justifiée'},
]


@mock_response(['/api/cg_ref_code/domain/MOTICLODAC', {'err': 0, 'data': MOTICLODAC_CODES}])
def test_nomenclature(app, rsa13, url):
    response = app.get(url + 'nomenclature/MOTICLODAC/')
    assert response.json == {
        'err': 0,
        'data': MOTICLODAC_CODES,
    }


PLATFORM_LIST = [{'dsp': 'LA', 'id': 11, 'name': 'ADPEI', 'role': 'Coordonnateur'}]


@mock_response(['/api/platform/', {'err': 0, 'data': PLATFORM_LIST}])
def test_platform(app, rsa13, url):
    response = app.get(url + 'platform/')
    assert response.json['data'] == PLATFORM_LIST


PLATFORM_DETAIL = {
    "id": 11,
    "name": "ADPEI",
    "dsp": "LA",
    "adr1": "ADPEI",
    "adr2": None,
    "adr3": None,
    "adr4": "18 BOULEVARD CAMILLE FLAMMARION",
    "adr5": None,
    "adr6": "13001 MARSEILLE",
    "tel": "0491110140",
    "queries": [
        {"id": 1, "name": "NON CONSULTÉ", "count": 727},
        {"id": 2, "name": "SANS RU", "count": 727},
        {"id": 3, "name": "SANS CONTRAT SUR LA PLATEFORME", "count": 231},
        {"id": 4, "name": "CONTRAT BIENTOT TERMINE", "count": 0},
        {"id": 5, "name": "SANS AUCUNE ACTION", "count": 44},
        {"id": 6, "name": "ACTION VALIDEE NON DEBUTEE NON CLOSE", "count": 111},
    ],
}


@mock_response(['/api/platform/11/', {'err': 0, 'data': PLATFORM_DETAIL}])
def test_platform_details(app, rsa13, url):
    response = app.get(url + 'platform/11/')
    assert response.json == {
        'err': 0,
        'data': PLATFORM_DETAIL,
    }


PLATFORM_REFERENT = [
    {
        "id": 324,
        "nom": "EHRMANN ",
        "prenom": "Jean Paul",
        "tel": None,
        "email": "john.doe@example.com",
        "role": "Coordonnateur",
        "statut": "Actif",
    },
    {
        "id": 239,
        "nom": "CHAUMONT ",
        "prenom": "Nadine",
        "tel": '090909090909',
        "email": "jane.doe@example.com",
        "role": "Accompagnateur",
        "statut": "Clos",
    },
]


@mock_response(['/api/platform/11/referent/', {'err': 0, 'data': PLATFORM_REFERENT}])
def test_platform_referent(app, rsa13, url):
    response = app.get(url + 'platform/11/referent/')
    assert response.json == {
        'err': 0,
        'data': PLATFORM_REFERENT,
    }


@mock_response(['/api/platform/11/referent/', {'err': 0, 'data': PLATFORM_REFERENT}])
def test_platform_referent_with_status(app, rsa13, url):
    response = app.get(url + 'platform/11/referent/?statut=Actif')
    assert response.json == {
        'err': 0,
        'data': [ref for ref in PLATFORM_REFERENT if ref['statut'] == 'Actif'],
    }


@mock_response(['/api/platform/11/referent/', {'err': 0}])
def test_platform_referent_post(app, rsa13, url):
    response = app.post_json(
        url + 'platform/11/referent/',
        params={
            'email': 'john.doe@example.com',
            'prenom': 'John',
            'nom': 'Doe',
            'tel': '0909090909',
        },
    )
    assert response.json == {'err': 0}


@mock_response(['/api/platform/11/referent/', {'err': 0}])
def test_platform_referent_post_empty_mail_and_tel(app, rsa13, url):
    response = app.post_json(
        url + 'platform/11/referent/',
        params={
            'email': '',
            'prenom': 'John',
            'nom': 'Doe',
            'tel': '',
        },
    )
    assert response.json == {'err': 0}


@mock_response(['/api/platform/11/referent/1/', {'err': 0}])
def test_platform_referent_update(app, rsa13, url):
    response = app.post_json(
        url + 'platform/11/referent/1/',
        params={
            'email': 'john.doe@example.com',
            'prenom': 'John',
            'nom': 'Doe',
            'tel': '0909090909',
            'statut': 'A',
        },
    )
    assert response.json == {'err': 0}


BENEFICIAIRE = {
    "id": 386981,
    "civilite": "MR",
    "nom": "AAABEFBAADF",
    "prenom": "ACCDCBE",
    "date_naissance": "1958-01-01",
    "actif": "Oui",
    "matricule": "193740",
    "code_postal": "13001",
    "commune": "MARSEILLE",
    "code_pi": "51",
    "referent": " ",
    "date_deb_affectation": "2019-03-11",
    "consulte": "Oui",
    "toppersdrodevorsa": "Oui",
}


@mock_response(['/api/platform/11/beneficiaire/', 'nom=AAABEFBAADF', {'err': 0, 'data': [BENEFICIAIRE]}])
def test_platform_beneficiaire_nom(app, rsa13, url):
    response = app.get(url + 'platform/11/beneficiaire/', params={'nom': 'AAABEFBAADF'})
    assert response.json == {
        "err": 0,
        "data": [BENEFICIAIRE],
    }


@mock_response(['/api/platform/11/beneficiaire/', 'matricule=193740', {'err': 0, 'data': [BENEFICIAIRE]}])
def test_platform_beneficiaire_matricule(app, rsa13, url):
    response = app.get(url + 'platform/11/beneficiaire/', params={'matricule': '193740'})
    assert response.json == {
        "err": 0,
        "data": [BENEFICIAIRE],
    }


@mock_response(['/api/platform/11/beneficiaire/', 'page=0', {'err': 0, 'data': [BENEFICIAIRE]}])
def test_platform_beneficiaire_page(app, rsa13, url):
    response = app.get(url + 'platform/11/beneficiaire/', params={'page': '0'})
    assert response.json == {
        "err": 0,
        "data": [BENEFICIAIRE],
    }


@mock_response(
    [
        '/api/platform/11/beneficiaire/',
        'page=0&nom=NOM&prenom=PRENOM&matricule=MATRICULE&referent=REFERENT',
        {'err': 0, 'data': [BENEFICIAIRE]},
    ]
)
def test_platform_beneficiaire_full(app, rsa13, url):
    response = app.get(
        url + 'platform/11/beneficiaire/',
        params={
            'page': '0',
            'nom': 'NOM',
            'prenom': 'PRENOM',
            'matricule': 'MATRICULE',
            'referent': 'REFERENT',
        },
    )
    assert response.json == {
        "err": 0,
        "data": [BENEFICIAIRE],
    }


BENEFICIAIRE_CSV = {
    "NUM_CAF": '1234',
    "CODE_PER": '1234',
    "PRENOM_PER": 'prenom',
    "DTNAI_PER": '1234',
    "ACTIF_PER": '1234',
    "NOM_PER": 'nom',
    "INSEE_ADR": '99999',
}


@mock_response(
    [
        '/api/platform/12/beneficiaire/csv/',
        'query=0&nom=bar&prenom=foo&matricule=xxx',
        {'err': 0, 'data': [BENEFICIAIRE_CSV]},
    ],
    [
        '/api/platform/11/beneficiaire/csv/',
        'query=1',
        {'err': 0, 'data': [BENEFICIAIRE_CSV]},
    ],
)
def test_platform_beneficiaire_csv(app, rsa13, url):
    response = app.get(
        url + 'platform/11/beneficiaire/csv/',
        params={
            'query': '1',
        },
    )
    assert (
        response.content == b'\xef\xbb\xbfNUM_CAF;CODE_PER;NOM_PER;PRENOM_PER;DTNAI_PER;ACTIF_PER;CODE_'
        b'PI;LIB_CODE_PI;TOPPERSDRODEVORSA;LIB_ETATDOSRSA;LIB_MOTIF_ETATDOSRSA;NB_JOUR'
        b'_DEPUIS_ARR;DATE_DEB;DATE_1IERE_CONS;DATE_DERNIERE_CONSULT;DATE_REELLE_RDV;N'
        b'UM_CINS;DATE_SIGN;DATE_DEB_CI;DATE_FIN_CI;REFERENT_CI;ACTION_EN_COURS;DELAI_'
        b'REGUL;PROC_EN_COURS;REFERENT_AFFECTATION;COMPL1_ADR;COMPL2_ADR;VO'
        b'IE_ADR;LIEU_DISTRIB_ADR;CP_ADR;VILLE_ADR;INSEE_ADR\r\n1234;1234;nom;prenom'
        b';1234;1234;;;;;;;;;;;;;;;;;;;;;;;;;;99999\r\n'
    )

    # customized on model
    rsa13.beneficiaire_csv_columns = '''\
NUM_CAF Numéro CAF
VILLE_ADR Ville'''
    rsa13.save()
    response = app.get(
        url + 'platform/11/beneficiaire/csv/',
        params={
            'query': '1',
        },
    )
    assert response.content == b'\xef\xbb\xbfNum\xc3\xa9ro CAF;Ville\r\n1234;\r\n'

    response = app.get(
        url + 'platform/12/beneficiaire/csv/',
        params={'query': '0', 'prenom': 'foo', 'nom': 'bar', 'matricule': 'xxx', 'referent': ''},
    )


BENEFICIAIRE_DETAIL = {
    'actif': 'Oui',
    'adresse': {
        'adr2': '8 RUE MISSION DE FRANCE',
        'adr3': '13001 MARSEILLE',
        'adr4': None,
        'adr5': None,
        'adr6': None,
    },
    'age': '62 ans',
    'civilite': 'MR',
    'code_pi': '51',
    'commentaire_ref': None,
    'conjoint': {
        'age': '52 ans',
        'id': 854379,
        'nom': 'AAABEFBAADF',
        'plateforme': 'PI51',
        'prenom': 'EEFBEFEC',
    },
    'date_de_naissance': '1958-01-01',
    'droit': {
        'date_demande': '2008-10-16',
        'etat': 'Droit ouvert et versable',
        'motif': None,
        'toppersdrodevorsa': 'Oui',
    },
    'enfants': [
        {'age': '16 ans', 'nom': 'DBFFFCDDDDCBAEAC', 'prenom': 'DCACBEAFFD'},
        {'age': '14 ans', 'nom': 'DBFFFCDDDDCBAEAC', 'prenom': 'BEDAEDEEBBCD'},
    ],
    'id': 386981,
    'lib_code_pi': "Pôle d'Insertion Marseille I",
    'matricule': '193740',
    'nom': 'AAABEFBAADF',
    'nomnaiss': 'EAEFEFDDDBEFDF',
    'numdemrsa': '13378013',
    'prenom': 'ACCDCBE',
    'referent': {'id': None, 'nom': None, 'prenom': None},
    'situation_familiale': {'date_debut': '2007-10-01', 'libelle': 'VIE MARITALE'},
}


@mock_response(['/api/platform/11/beneficiaire/386981/', {'err': 0, 'data': BENEFICIAIRE_DETAIL}])
def test_platform_beneficiaire_detail(app, rsa13, url):
    response = app.get(url + 'platform/11/beneficiaire/386981/')
    assert response.json == {
        'err': 0,
        'data': BENEFICIAIRE_DETAIL,
    }


BENEFICIAIRE_TRANSPORT = {'cumuls': [{'duree': 54, 'type': 'GTU'}]}


@mock_response(['/api/platform/11/beneficiaire/386981/telephone/', {'err': 0}])
def test_platform_beneficiaire_telephone(app, rsa13, url):
    response = app.post_json(
        url + 'platform/11/beneficiaire/386981/telephone/',
        params={'tel': '0909090909', 'commentaire': 'coin'},
    )
    assert response.json == {
        'err': 0,
    }


@mock_response(['/api/platform/11/beneficiaire/386981/telephone/0909090909/', {'err': 0}])
def test_platform_beneficiaire_telephone_update(app, rsa13, url):
    response = app.post_json(
        url + 'platform/11/beneficiaire/386981/telephone/0909090909/',
        params={'commentaire': 'coin'},
    )
    assert response.json == {
        'err': 0,
    }


@mock_response(['/api/platform/11/beneficiaire/386981/telephone/0909090909/', {'err': 0}])
def test_platform_beneficiaire_telephone_delete(app, rsa13, url):
    response = app.delete(
        url + 'platform/11/beneficiaire/386981/telephone/0909090909/',
    )
    assert response.json == {
        'err': 0,
    }


@mock_response(['/api/platform/11/beneficiaire/386981/email/', {'err': 0}])
def test_platform_beneficiaire_email(app, rsa13, url):
    response = app.post_json(
        url + 'platform/11/beneficiaire/386981/email/',
        params={'courriel': 'john.doe@example.com', 'commentaire': 'coin'},
    )
    assert response.json == {
        'err': 0,
    }


@mock_response(['/api/platform/11/beneficiaire/386981/email/john.doe@example.com/', {'err': 0}])
def test_platform_beneficiaire_email_update(app, rsa13, url):
    response = app.post_json(
        url + 'platform/11/beneficiaire/386981/email/john.doe@example.com/',
        params={'commentaire': 'coin'},
    )
    assert response.json == {
        'err': 0,
    }


@mock_response(['/api/platform/11/beneficiaire/386981/email/john.doe@example.com/', {'err': 0}])
def test_platform_beneficiaire_email_delete(app, rsa13, url):
    response = app.delete(
        url + 'platform/11/beneficiaire/386981/email/john.doe@example.com/',
    )
    assert response.json == {
        'err': 0,
    }


@mock_response(
    ['/api/platform/11/beneficiaire/386981/transport/', {'err': 0, 'data': BENEFICIAIRE_TRANSPORT}]
)
def test_platform_beneficiaire_transport(app, rsa13, url):
    response = app.get(url + 'platform/11/beneficiaire/386981/transport/')
    assert response.json == {'err': 0, 'data': BENEFICIAIRE_TRANSPORT}


BENEFICIAIRE_CONTRAT = [
    {
        'clos': 'Non',
        'date_deb': '2019-09-18',
        'date_fin': '2020-03-18',
        'decision': 'Validé',
        'duree': 6,
        'id': 15,
        'operateur': 'ADPEI',
        'plateforme': 'ADPEI',
        'referent': 'EHRMANN  J',
        'retab': 'Non',
    },
    {
        'clos': 'Oui',
        'date_deb': '2019-03-21',
        'date_fin': '2019-09-21',
        'decision': 'Validé',
        'duree': 6,
        'id': 14,
        'operateur': 'ADPEI',
        'plateforme': 'ADPEI',
        'referent': 'EHRMANN  J',
        'retab': 'Non',
    },
    {
        'clos': 'Oui',
        'date_deb': '2009-04-03',
        'date_fin': '2009-10-02',
        'decision': 'Validé',
        'duree': 6,
        'id': 0,
        'operateur': 'REPRISE HISTORIQUE LOGIFORM',
        'plateforme': 'REPRISE HISTORIQUE LOGIFORM',
        'referent': ' ',
        'retab': 'Non',
    },
]


@mock_response(['/api/platform/11/beneficiaire/386981/contrat/', {'err': 0, 'data': BENEFICIAIRE_CONTRAT}])
def test_platform_beneficiaire_contrat(app, rsa13, url):
    response = app.get(url + 'platform/11/beneficiaire/386981/contrat/')
    assert response.json == {
        'err': 0,
        'data': BENEFICIAIRE_CONTRAT,
    }


BENEFICIAIRE_CONTRAT_DETAIL = {
    'commentaire': 'Gratuité RTM refusée. En tant que bénéficiaire de la '
    'CMUC vous pouvez obtenir un tarif préférentiel sur '
    'le réseau RTM.',
    'date_clos': None,
    'date_cvs': None,
    'date_deb': '2019-09-18',
    'date_fin': '2020-03-18',
    'date_retab': None,
    'date_sign': '2019-09-03',
    'decision': 'Validé',
    'duree': 6,
    'id': 15,
    'motif_cvs': None,
    'operateur': 'ADPEI',
    'plateforme': 'ADPEI',
    'referent': {'commentaire': None, 'nom': 'EHRMANN ', 'prenom': 'Jean Paul'},
    'type_contrat': "Contrat d'Engagement Réciproque-Social",
}


@mock_response(
    ['/api/platform/11/beneficiaire/386981/contrat/15/', {'err': 0, 'data': BENEFICIAIRE_CONTRAT_DETAIL}]
)
def test_platform_beneficiaire_contrat_detail(app, rsa13, url):
    response = app.get(url + 'platform/11/beneficiaire/386981/contrat/15/')
    assert response.json == {
        'err': 0,
        'data': BENEFICIAIRE_CONTRAT_DETAIL,
    }


BENEFICIAIRE_ACTION = [
    {
        'clos': 'Oui',
        'contrat_id': 4,
        'date_deb': None,
        'date_fin': None,
        'date_preconisation': '2011-11-18',
        'id': 663774,
        'libelle': "Recherche autonome d'emploi",
        'validation': 'Non',
    },
    {
        'clos': 'Oui',
        'contrat_id': 0,
        'date_deb': '2009-04-03',
        'date_fin': '2009-10-02',
        'date_preconisation': '2009-09-05',
        'id': 7435,
        'libelle': 'Ne plus utilisé-Reprise historique Logiform',
        'validation': 'Oui',
    },
]


@mock_response(['/api/platform/11/beneficiaire/386981/action/', {'err': 0, 'data': BENEFICIAIRE_ACTION}])
def test_platform_beneficiaire_action(app, rsa13, url):
    response = app.get(url + 'platform/11/beneficiaire/386981/action/')
    assert response.json == {
        'err': 0,
        'data': BENEFICIAIRE_ACTION,
    }


@mock_response(
    ['/api/platform/11/beneficiaire/386981/action/', 'clos=oui', {'err': 0, 'data': BENEFICIAIRE_ACTION}]
)
def test_platform_beneficiaire_action_clos(app, rsa13, url):
    response = app.get(url + 'platform/11/beneficiaire/386981/action/', params={'clos': 'oui'})
    assert response.json == {
        'err': 0,
        'data': BENEFICIAIRE_ACTION,
    }


BENEFICIAIRE_ACTION_DETAIL = {
    'id': 663774,
    'contrat_id': 4,
    'sac': 'E3',
    'libelle': "Recherche autonome d'emploi",
    'date_deb': None,
    'date_fin': None,
    'date_preconisation': '2011-11-18',
    'date_cloture': '2012-01-12',
    'moticlodac': None,
    'lib_moticlodac': None,
    'validation': 'Non',
    'financement': {'montant_accorde': None, 'montant_demande': None},
    'commentaire_ref': None,
}


@mock_response(
    ['/api/platform/11/beneficiaire/386981/action/663774/', {'err': 0, 'data': BENEFICIAIRE_ACTION_DETAIL}]
)
def test_platform_beneficiaire_action_detail(app, rsa13, url):
    response = app.get(url + 'platform/11/beneficiaire/386981/action/663774/')
    assert response.json == {
        'err': 0,
        'data': BENEFICIAIRE_ACTION_DETAIL,
    }


@mock_response(['/api/platform/11/beneficiaire/386981/action/663774/', {'err': 0}])
def test_platform_beneficiaire_action_detail_update(app, rsa13, url):
    response = app.post_json(
        url + 'platform/11/beneficiaire/386981/action/663774/', params={'date_debug': '2021-01-01'}
    )
    assert response.json == {
        'err': 0,
    }


BENEFICIAIRE_FONDSAIDE = [
    {
        'avis_pi': {'avis': 'Refusée', 'date': '2019-07-08', 'montant': 0},
        'avis_sai': {'avis': None, 'date': None, 'montant': 0},
        'clos': 'Non',
        'code_tfi': 'FAI8',
        'demande': {'date': '2019-07-01', 'montant': 970},
        'id': 39605,
        'lib_tfi': 'FAI Permis B',
    }
]


@mock_response(
    ['/api/platform/11/beneficiaire/386981/fondsaide/', {'err': 0, 'data': BENEFICIAIRE_FONDSAIDE}]
)
def test_platform_beneficiaire_fondsaide(app, rsa13, url):
    response = app.get(url + 'platform/11/beneficiaire/386981/fondsaide/')
    # 365385/fonds-d-aide/fond-d-aide/39605/
    assert response.json == {
        'err': 0,
        'data': BENEFICIAIRE_FONDSAIDE,
    }


BENEFICIAIRE_FONDSAIDE_DETAIL = {
    'avis_pi': {'avis': 'Refusée', 'date': '2019-07-08', 'montant': 0},
    'budget': {
        'date_reception': None,
        'justificatifs': [
            {
                'conforme': None,
                'date_reception': None,
                'date_relance': None,
                'num_versement': 1,
                'reception': 'Non',
                'type': 'Document officiel de ' 'présentation au code de la ' 'route (ETG)',
            },
            {
                'conforme': None,
                'date_reception': None,
                'date_relance': None,
                'num_versement': 1,
                'reception': 'Non',
                'type': "Relevé d'identité bancaire",
            },
            {
                'conforme': None,
                'date_reception': None,
                'date_relance': None,
                'num_versement': 2,
                'reception': 'Non',
                'type': 'Document officiel de '
                'présentation à l’examen '
                'pratique du permis de '
                'conduire',
            },
        ],
        'nombre_versements': 2,
    },
    'cloture': {'date_cloture': None, 'date_relance': None},
    'code_tfi': 'FAI8',
    'decision_sai': {'date': None, 'decision': None, 'montant': 0},
    'demande': {'date': '2019-07-01', 'montant': 970},
    'id': 39605,
    'lib_tfi': 'FAI Permis B',
    'recours': {
        'date_decision': None,
        'date_demande': None,
        'decision': None,
        'montant': None,
    },
}


@mock_response(
    ['/api/platform/11/beneficiaire/386981/fondsaide/1/', {'err': 0, 'data': BENEFICIAIRE_FONDSAIDE_DETAIL}]
)
def test_platform_beneficiaire_fondsaide_detail(app, rsa13, url):
    response = app.get(url + 'platform/11/beneficiaire/386981/fondsaide/1/')
    assert response.json == {
        'err': 0,
        'data': BENEFICIAIRE_FONDSAIDE_DETAIL,
    }


BENEFICIAIRE_AFFECTATION = [
    {
        'id': 1599703,
        'dispoitif': 'LA',
        'plateforme': 'ADPEI',
        'code_pi': 51,
        'referent': ' ',
        'date_deb': '2019-03-11',
        'origine': 'CER',
    },
    {
        'id': 28726,
        'dispoitif': 'MDS',
        'plateforme': 'MDS PRESSENSE',
        'code_pi': 51,
        'referent': ' ',
        'date_deb': '2012-03-22',
        'origine': 'CER',
    },
]


@mock_response(
    ['/api/platform/11/beneficiaire/386981/affectation/', {'err': 0, 'data': BENEFICIAIRE_AFFECTATION}]
)
def test_platform_beneficiaire_affectation(app, rsa13, url):
    response = app.get(url + 'platform/11/beneficiaire/386981/affectation/')
    assert response.json == {
        'err': 0,
        'data': BENEFICIAIRE_AFFECTATION,
    }


BENEFICIAIRE_AFFECTATION_DETAIL = {
    'id': 1599703,
    'dispositif': 'LA',
    'plateforme': 'ADPEI',
    'code_pi': 51,
    'referent': {'nom': None, 'prenom': None},
    'erreur': 'Non',
    'date_deb': '2019-03-11',
    'origine': 'CER',
    'prescripteur': {'type': 'PI', 'dispositif': None, 'plateforme': None},
    'rendez-vous': {
        'date_prise': None,
        'relance': {'date': None, 'motif': None, 'lib_motif': None},
        'date_reelle': None,
        'resultat': None,
        'lib_resultat': None,
    },
    'fin': {'motif': None, 'lib_motif': None, 'date': None},
    'commentaire_ref': None,
}


@mock_response(
    [
        '/api/platform/11/beneficiaire/386981/affectation/1/',
        {'err': 0, 'data': BENEFICIAIRE_AFFECTATION_DETAIL},
    ]
)
def test_platform_beneficiaire_affectation_detail(app, rsa13, url):
    response = app.get(url + 'platform/11/beneficiaire/386981/affectation/1/')
    assert response.json == {
        'err': 0,
        'data': BENEFICIAIRE_AFFECTATION_DETAIL,
    }


@mock_response(
    [
        '/api/platform/11/beneficiaire/386981/affectation/1/',
        {'err': 0},
    ]
)
def test_platform_beneficiaire_affectation_detail_update(app, rsa13, url):
    response = app.post_json(
        url + 'platform/11/beneficiaire/386981/affectation/1/',
        params={'rendezvous': {'date_prise': '2020-01-01'}},
    )
    assert response.json == {
        'err': 0,
    }


BENEFICIAIRE_CONVO = {
    'convos_par_motif': [{'motif': "Absence de Contrat d'Engagement Réciproque", 'nombre': 2}],
    'derniere_consequence': {'date': None, 'consequence': None},
}


@mock_response(['/api/platform/11/beneficiaire/386981/convo/', {'err': 0, 'data': BENEFICIAIRE_CONVO}])
def test_platform_beneficiaire_convo(app, rsa13, url):
    response = app.get(url + 'platform/11/beneficiaire/386981/convo/')
    assert response.json == {
        'err': 0,
        'data': BENEFICIAIRE_CONVO,
    }


BENEFICIAIRE_EMPLOI = {
    'id': '6720658N',
    'date_sortie': None,
    'motif_sortie': None,
    'date_inscription': '2018-05-14',
    'date_dernier_ent': '2019-04-11',
    'code_rome': 'F1606',
    'lib_rome': 'Peintre tapissier / tapissière',
    'lib_modalite': 'RENFORCE',
    'lib_niveau': 'CERTIFICATION DE NIVEAU 5 (CAP, BEP)',
    'lib_secteur': None,
    'code_axe': '06',
    'lib_axe': "LEVEE DES FREINS PERIPHERIQUES A L'EMPLOI",
    'code_categorie': '1',
    'lib_categorie': 'PERSONNE SANS EMPLOI DISPONIBLE DUREE INDETERMINEE PLEIN TPS',
}


@mock_response(['/api/platform/11/beneficiaire/386981/emploi/', {'err': 0, 'data': BENEFICIAIRE_EMPLOI}])
def test_platform_beneficiaire_emploi(app, rsa13, url):
    response = app.get(url + 'platform/11/beneficiaire/386981/emploi/')
    assert response.json == {
        'err': 0,
        'data': BENEFICIAIRE_EMPLOI,
    }


@mock_response(['/api/platform/11/beneficiaire/386981/reaffectation/', {'err': 0}])
def test_platform_beneficiaire_reaffectation(app, rsa13, url):
    response = app.post_json(
        url + 'platform/11/beneficiaire/386981/reaffectation/', params={'motif': 'OK', 'commentaire': 'NOK'}
    )
    assert response.json == {
        'err': 0,
    }


@mock_response(
    [
        '/api/platform/11/facturation/periods/',
        {
            'err': 0,
            'data': [
                {
                    'id': '1234',
                    'text': 'Du 01/01/2022 au 31/03/2022',
                    'date_deb': '2022-01-01',
                    'date_fin': '2022-03-31',
                },
                {'text': 'Du 01/10/2021 au 31/12/2021', 'date_deb': '2021-10-01', 'date_fin': '2021-12-31'},
                {'text': 'Du 01/07/2021 au 30/09/2021', 'date_deb': '2021-07-01', 'date_fin': '2021-09-30'},
            ],
        },
    ]
)
def test_platform_facturation_periodes(app, rsa13, url):
    response = app.get(url + 'platform/11/facturation/periodes/')
    assert response.json == {
        'err': 0,
        'data': [
            {
                'date_deb': '2022-01-01',
                'date_fin': '2022-03-31',
                'id': '1234',
                'text': 'Du 01/01/2022 au 31/03/2022',
                'csv_url': 'http://testserver/rsa13/test/platform/11/facturation/csv/?date_deb=2022-01-01&date_fin=2022-03-31',
            },
            {
                'date_deb': '2021-10-01',
                'date_fin': '2021-12-31',
                'id': 'Du 01/10/2021 au 31/12/2021',
                'text': 'Du 01/10/2021 au 31/12/2021',
                'csv_url': 'http://testserver/rsa13/test/platform/11/facturation/csv/?date_deb=2021-10-01&date_fin=2021-12-31',
            },
            {
                'date_deb': '2021-07-01',
                'date_fin': '2021-09-30',
                'id': 'Du 01/07/2021 au 30/09/2021',
                'text': 'Du 01/07/2021 au 30/09/2021',
                'csv_url': 'http://testserver/rsa13/test/platform/11/facturation/csv/?date_deb=2021-07-01&date_fin=2021-09-30',
            },
        ],
    }


@mock_response(
    [
        '/api/platform/11/facturation/periods/',
        {
            'err': 0,
            'data': [
                {
                    'id': '1234',
                    'text': 'Du 01/01/2022 au 31/03/2022',
                    'date_deb': '2022-01-01',
                    'date_fin': '2022-03-31',
                },
                {'text': 'Du 01/10/2021 au 31/12/2021', 'date_deb': '2021-10-01', 'date_fin': '2021-12-31'},
                {'text': 'Du 01/07/2021 au 30/09/2021', 'date_deb': '2021-07-01', 'date_fin': '2021-09-30'},
            ],
        },
    ],
    [
        '/api/platform/11/facturation/csv',
        'date_deb=2021-10-01&date_fin=2021-12-31',
        {
            'err': 0,
            'data': [
                {
                    "PLATEFORME": "APDL MARTIGUES",
                    "MATRICULE": "1000017",
                    "NOM": "VKEOIFKQS",
                    "PRENOM": "SABINE",
                    "DTNAI": "1950-01-01",
                    "GENRE": "Femme",
                    "ROLE": "Demandeur",
                    "CODE_POSTAL": "13320",
                    "COMMUNE": "BOUC BEL AIR",
                    "DATE_SIGN": "2021-01-07",
                    "DATE_DEB": "2021-01-26",
                    "DUREE": 6,
                    "DATE_FIN": None,
                    "COEFFICIENT": 1.5,
                },
            ],
        },
    ],
)
def test_platform_facturation_csv(app, rsa13, url):
    response = app.get(url + 'platform/11/facturation/periodes/')
    response = app.get(response.json['data'][1]['csv_url'])
    stream = io.StringIO(response.content.decode('utf-8-sig'))
    assert list(csv.reader(stream, delimiter=';')) == [
        [
            "PLATEFORME",
            "MATRICULE",
            "NOM",
            "PRENOM",
            "DTNAI",
            "GENRE",
            "ROLE",
            "CODE_POSTAL",
            "COMMUNE",
            "DATE_SIGN",
            "DATE_DEB",
            "DUREE",
            "DATE_FIN",
            "COEFFICIENT",
        ],
        [
            'APDL MARTIGUES',
            '1000017',
            'VKEOIFKQS',
            'SABINE',
            '1950-01-01',
            'Femme',
            'Demandeur',
            '13320',
            'BOUC BEL AIR',
            '2021-01-07',
            '2021-01-26',
            '6',
            '',
            '1.5',
        ],
    ]

    # customized on model
    rsa13.facturation_csv_columns = '''\
PLATEFORME
DUREE'''
    rsa13.save()
    response = app.get(url + 'platform/11/facturation/periodes/')
    response = app.get(response.json['data'][1]['csv_url'])
    stream = io.StringIO(response.content.decode('utf-8-sig'))
    assert list(csv.reader(stream, delimiter=';')) == [
        [
            'PLATEFORME',
            'DUREE',
        ],
        [
            'APDL MARTIGUES',
            '6',
        ],
    ]


@mock_response(
    [
        '/api/platform/11/beneficiaire/sorti/csv',
        {
            "err": 0,
            "data": [
                {
                    "NUM_CAF": "372927",
                    "CODE_PER": 415443,
                    "NOM_PER": "DCFFEBABBDDCDEC",
                    "PRENOM_PER": "CBDACDCFEBBAA",
                    "DTNAI_PER": "1972-01-01",
                    "CP_PER": "13004",
                    "COMMUNE_PER": "MARSEILLE",
                    "ACTIF_PER": "Oui",
                    "CODE_PI": 53,
                    "LIB_CODE_PI": "Pôle d'insertion Marseille III",
                    "TOPPERSDRODEVORSA": "N",
                    "LIB_ETATDOSRSA": "Droit clos",
                    "LIB_MOTIF_ETATDOSRSA": "Clôture suite à échéance (4 mois sans droits)",
                    "PLT_DT_DEB_AFF": "2021-10-05",
                    "PLT_DT_FIN_AFF": "2022-06-13",
                    "PLT_MOTIF_FIN_ACC": None,
                    "PLT_COMMENTAIRE_REF": (
                        '29/11/2021 Mme présente au RDV, mais pas de CER car plus '
                        'de RSA. Titulaire d\'une pension d\'invalidité elle a un complément d\'ASI.\nE.CASTORI'
                    ),
                    "PLT_NUM_CI": None,
                    "PLT_PLATEFORME_CI": None,
                    "PLT_OPERATEUR_CI": None,
                    "PLT_REFERENT_CI": " ",
                    "PLT_DECISION_CI": None,
                    "PLT_DUREE_CI": None,
                    "PLT_DATE_DEB_CI": None,
                    "PLT_DATE_FIN_CI": None,
                    "NOUVEAU_DT_DEB_AFF": "2022-06-13",
                    "NOUVEAU_AFF": "SORTIE",
                    "NOUVEAU_COMMENTAIRE_PI": None,
                    "NOUVEAU_NUM_CI": None,
                    "NOUVEAU_PLATEFORME_CI": None,
                    "NOUVEAU_OPERATEUR_CI": None,
                    "NOUVEAU_REFERENT_CI": None,
                    "NOUVEAU_DECISION_CI": None,
                    "NOUVEAU_DUREE_CI": None,
                    "NOUVEAU_DATE_DEB_CI": None,
                    "NOUVEAU_DATE_FIN_CI": None,
                },
                {
                    "NUM_CAF": "1677380",
                    "CODE_PER": 816754,
                    "NOM_PER": "EBBCAAFBDCCF",
                    "PRENOM_PER": "CCCADFBCBCEBCDCEBC",
                    "DTNAI_PER": "1956-01-01",
                    "CP_PER": "13012",
                    "COMMUNE_PER": "MARSEILLE 12",
                    "ACTIF_PER": "Oui",
                    "CODE_PI": 53,
                    "LIB_CODE_PI": "Pôle d'insertion Marseille III",
                    "TOPPERSDRODEVORSA": "N",
                    "LIB_ETATDOSRSA": "Droit clos",
                    "LIB_MOTIF_ETATDOSRSA": "Clôture suite à échéance (4 mois sans droits)",
                    "PLT_DT_DEB_AFF": "2021-10-15",
                    "PLT_DT_FIN_AFF": "2022-06-13",
                    "PLT_MOTIF_FIN_ACC": None,
                    "PLT_COMMENTAIRE_REF": None,
                    "PLT_NUM_CI": None,
                    "PLT_PLATEFORME_CI": None,
                    "PLT_OPERATEUR_CI": None,
                    "PLT_REFERENT_CI": " ",
                    "PLT_DECISION_CI": None,
                    "PLT_DUREE_CI": None,
                    "PLT_DATE_DEB_CI": None,
                    "PLT_DATE_FIN_CI": None,
                    "NOUVEAU_DT_DEB_AFF": "2022-06-13",
                    "NOUVEAU_AFF": "SORTIE",
                    "NOUVEAU_COMMENTAIRE_PI": None,
                    "NOUVEAU_NUM_CI": "16",
                    "NOUVEAU_PLATEFORME_CI": "CCO CANTINI",
                    "NOUVEAU_OPERATEUR_CI": "CCO",
                    "NOUVEAU_REFERENT_CI": "O BOBEUF",
                    "NOUVEAU_DECISION_CI": "Validé",
                    "NOUVEAU_DUREE_CI": "4",
                    "NOUVEAU_DATE_DEB_CI": "2021-10-18",
                    "NOUVEAU_DATE_FIN_CI": "2022-02-18",
                },
            ],
        },
    ],
)
def test_platform_beneficiaire_sorti_csv(app, rsa13, url):
    response = app.get(url + 'platform/11/beneficiaire/sorti/csv/')
    stream = io.StringIO(response.content.decode('utf-8-sig'))
    assert list(csv.reader(stream, delimiter=';')) == [
        [
            'NUM_CAF',
            'CODE_PER',
            'NOM_PER',
            'PRENOM_PER',
            'DTNAI_PER',
            'CP_PER',
            'COMMUNE_PER',
            'ACTIF_PER',
            'CODE_PI',
            'LIB_CODE_PI',
            'TOPPERSDRODEVORSA',
            'LIB_ETATDOSRSA',
            'LIB_MOTIF_ETATDOSRSA',
            'PLT_DT_DEB_AFF',
            'PLT_DT_FIN_AFF',
            'PLT_MOTIF_FIN_ACC',
            'PLT_COMMENTAIRE_REF',
            'PLT_NUM_CI',
            'PLT_PLATEFORME_CI',
            'PLT_OPERATEUR_CI',
            'PLT_REFERENT_CI',
            'PLT_DECISION_CI',
            'PLT_DUREE_CI',
            'PLT_DATE_DEB_CI',
            'PLT_DATE_FIN_CI',
            'NOUVEAU_DT_DEB_AFF',
            'NOUVEAU_AFF',
            'NOUVEAU_COMMENTAIRE_PI',
            'NOUVEAU_NUM_CI',
            'NOUVEAU_PLATEFORME_CI',
            'NOUVEAU_OPERATEUR_CI',
            'NOUVEAU_REFERENT_CI',
            'NOUVEAU_DECISION_CI',
            'NOUVEAU_DUREE_CI',
            'NOUVEAU_DATE_DEB_CI',
            'NOUVEAU_DATE_FIN_CI',
        ],
        [
            '372927',
            '415443',
            'DCFFEBABBDDCDEC',
            'CBDACDCFEBBAA',
            '1972-01-01',
            '13004',
            'MARSEILLE',
            'Oui',
            '53',
            "Pôle d'insertion Marseille III",
            'N',
            'Droit clos',
            'Clôture suite à échéance (4 mois sans droits)',
            '2021-10-05',
            '2022-06-13',
            '',
            '29/11/2021 Mme présente au RDV, mais pas de CER car plus de RSA. Titulaire '
            "d'une pension d'invalidité elle a un complément d'ASI.\n"
            'E.CASTORI',
            '',
            '',
            '',
            ' ',
            '',
            '',
            '',
            '',
            '2022-06-13',
            'SORTIE',
            '',
            '',
            '',
            '',
            '',
            '',
            '',
            '',
            '',
        ],
        [
            '1677380',
            '816754',
            'EBBCAAFBDCCF',
            'CCCADFBCBCEBCDCEBC',
            '1956-01-01',
            '13012',
            'MARSEILLE 12',
            'Oui',
            '53',
            "Pôle d'insertion Marseille III",
            'N',
            'Droit clos',
            'Clôture suite à échéance (4 mois sans droits)',
            '2021-10-15',
            '2022-06-13',
            '',
            '',
            '',
            '',
            '',
            ' ',
            '',
            '',
            '',
            '',
            '2022-06-13',
            'SORTIE',
            '',
            '16',
            'CCO CANTINI',
            'CCO',
            'O BOBEUF',
            'Validé',
            '4',
            '2021-10-18',
            '2022-02-18',
        ],
    ]

    # customized on model
    rsa13.sorti_csv_columns = '''
NUM_CAF
CODE_PER
'''
    rsa13.save()
    response = app.get(url + 'platform/11/beneficiaire/sorti/csv/')
    stream = io.StringIO(response.content.decode('utf-8-sig'))
    assert list(csv.reader(stream, delimiter=';')) == [
        ['NUM_CAF', 'CODE_PER'],
        ['372927', '415443'],
        ['1677380', '816754'],
    ]


@mock_response(
    [
        '/api/sousaction/',
        {
            'err': 0,
            'data': [
                {
                    "id": "A1",
                    "text": "A1 - DAIE 13",
                    "description": "DISPOSITIF d'Accompagnement et d'Insertion par l'Emploi.\n",
                },
                {
                    "id": "A10",
                    "text": "A10 - Accompagnement Global",
                    "description": (
                        'Accompagnement de Pôle Emploi qui  permet la prise en charge simultanée de '
                        'problématiques sociales et professionnelles, par l’intervention conjointe '
                        'd’un travailleur social et d’un conseiller dédié de Pôle Emploi.'
                    ),
                },
                {
                    "id": "A11",
                    "text": "A11 - MODALH",
                    "description": (
                        'C’est un diagnostic qui évalue l’employabilité ou la nécessité '
                        'd’un accès à une prestation plus adaptée (AAH) pour les bénéficiaires '
                        'du RSA ayant un CER santé. La prescription est uniquement assuré par '
                        'le médecin du Pôle d’insertion.'
                    ),
                },
                {
                    "id": "A12",
                    "text": "A12 - PHARE",
                    "description": (
                        'C’est un accompagnement pour le retour à l’emploi des bénéficiaires '
                        'du RSA reconnus travailleur handicapé. Il se formalise par la réalisation d’un CER.'
                    ),
                },
                {"id": "A13", "text": "A13 - CAP Emploi", "description": None},
                {
                    "id": "A14",
                    "text": "A14 - Accompagnement Global spécialisé",
                    "description": (
                        'A utiliser dans le cadre de la convention signée avec trois lieux d\'accueil '
                        'sur l’expérimentation de l’accompagnement global spécialisé'
                    ),
                },
                {"id": "A15", "text": "A15 - Boost Emploi", "description": None},
                {
                    "id": "A16",
                    "text": "A16 - Lieu accueil spécialisé travailleur indépendant",
                    "description": None,
                },
            ],
        },
    ]
)
def test_sous_action(app, rsa13, url):
    response = app.get(url + 'sous-action/')
    assert response.json == {
        'data': [
            {
                'description': "DISPOSITIF d'Accompagnement et d'Insertion par " "l'Emploi.\n",
                'id': 'A1',
                'text': 'A1 - DAIE 13',
            },
            {
                'description': 'Accompagnement de Pôle Emploi qui  permet la prise '
                'en charge simultanée de problématiques sociales et '
                'professionnelles, par l’intervention conjointe d’un '
                'travailleur social et d’un conseiller dédié de Pôle '
                'Emploi.',
                'id': 'A10',
                'text': 'A10 - Accompagnement Global',
            },
            {
                'description': 'C’est un diagnostic qui évalue l’employabilité ou '
                'la nécessité d’un accès à une prestation plus '
                'adaptée (AAH) pour les bénéficiaires du RSA ayant '
                'un CER santé. La prescription est uniquement assuré '
                'par le médecin du Pôle d’insertion.',
                'id': 'A11',
                'text': 'A11 - MODALH',
            },
            {
                'description': 'C’est un accompagnement pour le retour à l’emploi '
                'des bénéficiaires du RSA reconnus travailleur '
                'handicapé. Il se formalise par la réalisation d’un '
                'CER.',
                'id': 'A12',
                'text': 'A12 - PHARE',
            },
            {'description': None, 'id': 'A13', 'text': 'A13 - CAP Emploi'},
            {
                'description': 'A utiliser dans le cadre de la convention signée '
                "avec trois lieux d'accueil sur l’expérimentation de "
                'l’accompagnement global spécialisé',
                'id': 'A14',
                'text': 'A14 - Accompagnement Global spécialisé',
            },
            {'description': None, 'id': 'A15', 'text': 'A15 - Boost Emploi'},
            {
                'description': None,
                'id': 'A16',
                'text': 'A16 - Lieu accueil spécialisé travailleur indépendant',
            },
        ],
        'err': 0,
    }


def test_csv_columns_migration(transactional_db, settings):
    migrate_from = [('rsa13', '0001_initial')]
    migrate_to = [('rsa13', '0002_add_csv_columns_fields')]

    executor = MigrationExecutor(connection)
    old_apps = executor.loader.project_state(migrate_from).apps

    # state of the db is not important
    executor.migrate(migrate_from)

    RSA13Resource = old_apps.get_model('rsa13', 'RSA13Resource')
    resource = RSA13Resource.objects.create()

    settings.RSA13_CSV_COLUMNS = [('A', '2'), 'B']
    settings.RSA13_FACTURATION_CSV_COLUMNS = ['C', 'D']
    settings.RSA13_BENEFICIAIRE_SORTI_CSV_COLUMNS = ['E', 'F']

    executor = MigrationExecutor(connection)
    executor.migrate(migrate_to)
    executor.loader.build_graph()
    apps = executor.loader.project_state(migrate_to).apps

    RSA13Resource = apps.get_model('rsa13', 'RSA13Resource')
    resource = RSA13Resource.objects.get()
    assert resource.beneficiaire_csv_columns == 'A 2\nB'
    assert resource.facturation_csv_columns == 'C\nD'
    assert resource.sorti_csv_columns == 'E\nF'


def test_manager(app, admin_user):
    app = login(app)
    resp = app.get('/manage/')
    resp = resp.click('Add Connector')
    resp = resp.click('RSA CD13')
    resp.forms[0]['title'] = 'Test Connector'
    resp.forms[0]['slug'] = 'test-connector'
    resp.forms[0]['description'] = 'Connector for a simple test'
    resp.forms[0]['webservice_base_url'] = 'https://example.com/'
    resp = resp.forms[0].submit().follow()
    assert 'Test Connector' in resp.text

    instance = RSA13Resource.objects.get()
    for key, value in DEFAULTS.items():
        assert getattr(instance, key) == dump_csv_columns(value)

    resp = resp.click('Edit')
    resp.form.set('beneficiaire_csv_columns', 'NUM_CAF')
    resp.form.set('facturation_csv_columns', 'MATRICULE')
    resp.form.set('sorti_csv_columns', 'NUM_CAF')
    resp = resp.form.submit().follow()
    instance = RSA13Resource.objects.get()
    for key in DEFAULTS:
        assert getattr(instance, key) in ['NUM_CAF', 'MATRICULE']

    resp = resp.click('Edit')
    for key in DEFAULTS:
        assert resp.form[key].value in ['NUM_CAF', 'MATRICULE']
