#!/usr/bin/env python3
# -*- mode: python -*-
# -*- coding: utf-8 -*-

"""Exemple utilisation API ScoDoc 9 avec jeton obtenu par basic authentication

    Usage:
        cd /opt/scodoc/tests/api
        python -i exemple-api-basic.py


Pour utiliser l'API, (sur une base quelconque):
```
cd /opt/scodoc/tests/api

python -i exemple-api-basic.py
>>> admin_h = get_auth_headers("admin", "xxx")
>>> GET("/etudiant/etudid/14806", headers=admin_h)
```

Créer éventuellement un fichier `.env` dans /opt/scodoc/tests/api
avec la config du client API:
```
    SCODOC_URL = "http://localhost:5000/"
    API_USER = "admin"
    API_PASSWORD = "test"
```
"""

from pprint import pprint as pp
import requests
import sys
import urllib3
from setup_test_api import (
    API_PASSWORD,
    API_URL,
    API_USER,
    APIError,
    CHECK_CERTIFICATE,
    get_auth_headers,
    GET,
    POST_JSON,
    SCODOC_URL,
)


def logout_api_user():
    r = requests.delete(API_URL + "/tokens", headers=HEADERS, verify=CHECK_CERTIFICATE)
    assert r.status_code == 204


if not CHECK_CERTIFICATE:
    urllib3.disable_warnings()

print(f"SCODOC_URL={SCODOC_URL}")
print(f"API URL={API_URL}")


HEADERS = get_auth_headers(API_USER, API_PASSWORD)
admin_h = get_auth_headers("admin_api", "admin_api")

departements = GET("/departements", headers=HEADERS)
pp(departements)

# Liste de tous les étudiants en cours (de tous les depts)
etuds = GET("/etudiants/courants", headers=HEADERS)

print(f"{len(etuds)} étudiants courants")

raise Exception("arret en mode interactif")

# ---------------- DIVERS ESSAIS EN MODE INTERACTIF
# ---------------- A ADAPTER A VOS BESOINS

# Bulletin d'un BUT
formsemestre_id = 1063  # A adapter
etudid = 16450
bul = GET(
    f"/etudiant/etudid/{etudid}/formsemestre/{formsemestre_id}/bulletin",
    headers=HEADERS,
)

# d'un DUT
formsemestre_id = 1062  # A adapter
etudid = 16309
bul_dut = GET(
    f"/etudiant/etudid/{etudid}/formsemestre/{formsemestre_id}/bulletin",
    headers=HEADERS,
)


# Infos sur un étudiant
etudid = 3561
code_nip = "11303314"
etud = GET(f"/etudiant/etudid/{etudid}", headers=HEADERS)
print(etud)

etud = GET(f"/etudiant/nip/{code_nip}", headers=HEADERS)
print(etud)

sems = GET(f"/etudiant/etudid/{etudid}/formsemestres", headers=HEADERS)
print("\n".join([s["titre_num"] for s in sems]))

sems = GET(f"/etudiant/nip/{code_nip}/formsemestres", headers=HEADERS)
print("\n".join([s["titre_num"] for s in sems]))

# Evaluation
evals = GET("/evaluations/1")

# Partitions d'un BUT
formsemestre_id = 1063  # A adapter
partitions = GET(f"/formsemestre/{formsemestre_id}/partitions", headers=HEADERS)
print(partitions)
pid = partitions[1]["id"]
partition = GET(f"/partition/{pid}", headers=HEADERS)
print(partition)
group_id = partition["groups"][0]["id"]
etuds = GET(f"/group/{group_id}/etudiants", headers=HEADERS)
print(f"{len(etuds)} étudiants")
pp(etuds[1])

etuds_dem = GET(f"/group/{group_id}/etudiants/query?etat=D", headers=HEADERS)
print(f"{len(etuds_dem)} étudiants")

etudid = 16650
group_id = 5315
POST(f"/group/{group_id}/set_etudiant/{etudid}", headers=HEADERS)


POST_JSON(
    f"/partition/{pid}/group/create", data={"group_name": "Omega10"}, headers=HEADERS
)
partitions = GET(f"/formsemestre/{formsemestre_id}/partitions", headers=HEADERS)
pp(partitions)

POST_JSON(f"/group/5559/delete", headers=HEADERS)
POST_JSON(f"/group/5327/edit", data={"group_name": "TDXXX"}, headers=HEADERS)

# --------- Toutes les bulletins, un à un, et les décisions de jury d'un semestre
formsemestre_id = 911
etuds = GET(f"/formsemestre/{formsemestre_id}/etudiants", headers=admin_h)
etudid = 16450
bul = GET(
    f"/etudiant/etudid/{etudid}/formsemestre/{formsemestre_id}/bulletin",
    headers=HEADERS,
)
for etud in etuds:
    bul = GET(
        f"/etudiant/etudid/{etud['id']}/formsemestre/{formsemestre_id}/bulletin",
        headers=HEADERS,
    )
    sys.stdout.write(".")
    sys.stdout.flush()

print("")
decisions = GET(f"/formsemestre/{formsemestre_id}/decisions_jury", headers=HEADERS)

# Decisions de jury des _tous_ les formsemestre, un à un, en partant de l'id le plus élevé
formsemestres = GET("/formsemestres/query", headers=HEADERS)
formsemestres.sort(key=lambda s: s["id"], reverse=1)
print(f"###### Testing {len(formsemestres)} formsemestres...")
for formsemestre in formsemestres:
    print(formsemestre["session_id"])
    try:
        decisions = GET(
            f"/formsemestre/{formsemestre['id']}/decisions_jury", headers=HEADERS
        )
    except APIError as exc:
        if exc.payload.get("message") != "non implemente":
            raise
        decisions = []
    print(f"{len(decisions)} decisions")

# --------- A été passé dans les tests unitaires:

# 0- Prend un étudiant au hasard dans le semestre
etud = GET(f"/formsemestre/{formsemestre_id}/etudiants", headers=HEADERS)[10]
etudid = etud["id"]

# 1- Crée une partition, puis la change de nom
js = POST_JSON(
    f"/formsemestre/{formsemestre_id}/partition/create",
    data={"partition_name": "PART"},
)
partition_id = js["id"]
POST_JSON(
    f"/partition/{partition_id}/edit",
    data={"partition_name": "PART1", "show_in_lists": True},
    headers=HEADERS,
)

# 2- Crée un groupe
js = POST_JSON(
    f"/partition/{partition_id}/group/create",
    data={"group_name": "G1"},
    headers=HEADERS,
)
group_1 = js["id"]

# 3- Crée deux autres groupes
js = POST_JSON(
    f"/partition/{partition_id}/group/create",
    data={"group_name": "G2"},
    headers=HEADERS,
)
js = POST_JSON(
    f"/partition/{partition_id}/group/create",
    data={"group_name": "G3"},
    headers=HEADERS,
)

# 4- Affecte étudiant au groupe G1
POST_JSON(f"/group/{group_1}/set_etudiant/{etudid}", headers=HEADERS)

# 5- retire du groupe
POST_JSON(f"/group/{group_1}/remove_etudiant/{etudid}", headers=HEADERS)

# 6- affecte au groupe G2
partition = GET(f"/partition/{partition_id}")
assert len(partition["groups"]) == 3
group_2 = [g for g in partition["groups"].values() if g["group_name"] == "G2"][0]["id"]
POST_JSON(f"/group/{group_2}/set_etudiant/{etudid}", headers=HEADERS)

# 7- Membres du groupe
etuds_g2 = GET(f"/group/{group_2}/etudiants", headers=HEADERS)
assert len(etuds_g2) == 1
assert etuds_g2[0]["id"] == etudid

# 8- Ordres des groupes
group_3 = [g for g in partition["groups"].values() if g["group_name"] == "G3"][0]["id"]

POST_JSON(
    f"/partition/{partition_id}/groups/order",
    data=[group_2, group_1, group_3],
    headers=HEADERS,
)

new_groups = [
    g["id"]
    for g in GET(f"/partition/{partition_id}", headers=HEADERS)["groups"].values()
]
assert new_groups == [group_2, group_1, group_3]

# 9- Suppression
POST_JSON(f"/partition/{partition_id}/delete")
# ------

# Tests accès API:
"""
 * En mode API:
    Avec admin:
     - GET, POST ci-dessus : OK
    Avec user ayant ScoView (rôle LecteurAPI)
     - idem
    Avec user sans ScoView:
     - GET et POST: erreur 403
 * En mode Web:
    admin: GET
    user : GET = 403
"""

#
POST_JSON(
    "/partition/2264/groups/order",
    data=[5563, 5562, 5561, 5560, 5558, 5557, 5316, 5315],
    headers=HEADERS,
)

POST_JSON(
    "/formsemestre/1063/partitions/order",
    data=[2264, 2263, 2265, 2266, 2267, 2372, 2378],
    headers=HEADERS,
)


GET(f"/partition/2264", headers=HEADERS)

# Recherche de formsemestres
sems = GET(f"/formsemestres/query?etape_apo=V1RT&annee_scolaire=2021", headers=HEADERS)

# Table récap:
pp(GET(f"/formsemestre/1063/resultats", headers=HEADERS)[0])

pp(GET(f"/formsemestre/880/resultats", headers=HEADERS)[0])

# # sems est une liste de semestres (dictionnaires)
# for sem in sems:
#     if sem["etat"]:
#         break

# if sem["etat"] == "0":
#     raise ScoError("Aucun semestre non verrouillé !")

# # Affiche le  semestre trouvé:
# pp(sem)