# -*- coding: utf-8 -*-

"""Test Logos


Utiliser comme: 
    pytest tests/unit/test_logos.py

"""
from pathlib import Path
from shutil import copytree, copy, rmtree

import pytest as pytest
from _pytest.python_api import approx

import app
from app import db
from app.models import Departement
import app.scodoc.sco_utils as scu
from app.scodoc.sco_logos import (
    find_logo,
    Logo,
    list_logos,
    GLOBAL,
    write_logo,
    delete_logo,
)

RESOURCES_DIR = "/opt/scodoc/tests/ressources/test_logos"


@pytest.fixture
def create_dept(test_client):
    """Crée 2 départements:
    return departements object
    """
    dept1 = Departement(acronym="RT")
    dept2 = Departement(acronym="INFO")
    dept3 = Departement(acronym="GEA")
    db.session.add(dept1)
    db.session.add(dept2)
    db.session.add(dept3)
    db.session.commit()
    yield dept1, dept2, dept3
    db.session.delete(dept1)
    db.session.delete(dept2)
    db.session.delete(dept3)
    db.session.commit()


@pytest.fixture
def create_logos(create_dept):
    """Crée les logos:
    ...logos --+-- logo_A.jpg
               +-- logo_C.jpg
               +-- logo_D.png
               +-- logo_E.jpg
               +-- logo_F.jpeg
               +-- logos_{d1} --+-- logo_A.jpg
               |                +-- logo_B.jpg
               +-- logos_{d2} --+-- logo_A.jpg

    """
    dept1, dept2, dept3 = create_dept
    d1 = dept1.id
    d2 = dept2.id
    d3 = dept3.id
    FILE_LIST = ["logo_A.jpg", "logo_C.jpg", "logo_D.png", "logo_E.jpg", "logo_F.jpeg"]
    for fn in FILE_LIST:
        from_path = Path(RESOURCES_DIR).joinpath(fn)
        to_path = Path(scu.SCODOC_LOGOS_DIR).joinpath(fn)
        copy(from_path.absolute(), to_path.absolute())
    copytree(
        f"{RESOURCES_DIR}/logos_1",
        f"{scu.SCODOC_LOGOS_DIR}/logos_{d1}",
    )
    copytree(
        f"{RESOURCES_DIR}/logos_2",
        f"{scu.SCODOC_LOGOS_DIR}/logos_{d2}",
    )
    yield None
    rmtree(f"{scu.SCODOC_LOGOS_DIR}/logos_{d1}")
    rmtree(f"{scu.SCODOC_LOGOS_DIR}/logos_{d2}")
    # rm files
    for fn in FILE_LIST:
        to_path = Path(scu.SCODOC_LOGOS_DIR).joinpath(fn)
        to_path.unlink()


def test_select_global_only(create_logos):
    C_logo = app.scodoc.sco_logos.find_logo(logoname="C")
    assert C_logo.filepath == f"{scu.SCODOC_LOGOS_DIR}/logo_C.jpg"


def test_select_local_only(create_dept, create_logos):
    dept1, dept2, dept3 = create_dept
    B_logo = app.scodoc.sco_logos.find_logo(logoname="B", dept_id=dept1.id)
    assert B_logo.filepath == f"{scu.SCODOC_LOGOS_DIR}/logos_{dept1.id}/logo_B.jpg"


def test_select_local_override_global(create_dept, create_logos):
    dept1, dept2, dept3 = create_dept
    A1_logo = app.scodoc.sco_logos.find_logo(logoname="A", dept_id=dept1.id)
    assert A1_logo.filepath == f"{scu.SCODOC_LOGOS_DIR}/logos_{dept1.id}/logo_A.jpg"


def test_select_global_with_strict(create_dept, create_logos):
    dept1, dept2, dept3 = create_dept
    A_logo = app.scodoc.sco_logos.find_logo(logoname="A", dept_id=dept1.id, strict=True)
    assert A_logo.filepath == f"{scu.SCODOC_LOGOS_DIR}/logos_{dept1.id}/logo_A.jpg"


def test_looks_for_non_existant_should_give_none(create_dept, create_logos):
    # search for a local non-existant logo returns None
    dept1, dept2, dept3 = create_dept
    no_logo = app.scodoc.sco_logos.find_logo(logoname="Z", dept_id=dept1.id)
    assert no_logo is None


def test_looks_localy_for_a_global_should_give_none(create_dept, create_logos):
    # search for a local non-existant logo returns None
    dept1, dept2, dept3 = create_dept
    no_logo = app.scodoc.sco_logos.find_logo(
        logoname="C", dept_id=dept1.id, strict=True
    )
    assert no_logo is None


def test_get_jpg_data(create_dept, create_logos):
    logo = find_logo("A", dept_id=None)
    assert logo is not None
    logo.select()
    assert logo.logoname == "A"
    assert logo.suffix == "jpg"
    assert logo.filename == "A.jpg"
    assert logo.size == (224, 131)
    assert logo.mm == approx((9.38, 5.49), 0.1)


def test_get_png_without_data(create_dept, create_logos):
    logo = find_logo("D", dept_id=None)
    assert logo is not None
    logo.select()
    assert logo.logoname == "D"
    assert logo.suffix == "png"
    assert logo.filename == "D.png"
    assert logo.size == (140, 131)
    assert logo.density is None
    assert logo.mm is None


def test_delete_unique_global_jpg_logo(create_dept, create_logos):
    from_path = Path(RESOURCES_DIR).joinpath("logo_A.jpg")
    to_path = Path(scu.SCODOC_LOGOS_DIR).joinpath("logo_W.jpg")
    copy(from_path.absolute(), to_path.absolute())
    assert to_path.exists()
    delete_logo(name="W")
    assert not to_path.exists()


def test_delete_unique_local_jpg_logo(create_dept, create_logos):
    dept1, dept2, dept3 = create_dept
    from_path = Path(RESOURCES_DIR).joinpath("logo_A.jpg")
    to_path = Path(scu.SCODOC_LOGOS_DIR).joinpath(f"logos_{dept1.id}", "logo_W.jpg")
    copy(from_path.absolute(), to_path.absolute())
    assert to_path.exists()
    delete_logo(name="W", dept_id=dept1.id)
    assert not to_path.exists()


def test_delete_multiple_local_jpg_logo(create_dept, create_logos):
    dept1, dept2, dept3 = create_dept
    from_path_A = Path(RESOURCES_DIR).joinpath("logo_A.jpg")
    to_path_A = Path(scu.SCODOC_LOGOS_DIR).joinpath(f"logos_{dept1.id}", "logo_V.jpg")
    from_path_B = Path(RESOURCES_DIR).joinpath("logo_D.png")
    to_path_B = Path(scu.SCODOC_LOGOS_DIR).joinpath(f"logos_{dept1.id}", "logo_V.png")
    copy(from_path_A.absolute(), to_path_A.absolute())
    copy(from_path_B.absolute(), to_path_B.absolute())
    assert to_path_A.exists()
    assert to_path_B.exists()
    delete_logo(name="V", dept_id=dept1.id)
    assert not to_path_A.exists()
    assert not to_path_B.exists()


def test_create_global_jpg_logo(create_dept, create_logos):
    path = Path(f"{RESOURCES_DIR}/logo_C.jpg")
    stream = path.open("rb")
    logo_path = Path(scu.SCODOC_LOGOS_DIR).joinpath("logo_X.jpg")
    assert not logo_path.exists()
    write_logo(stream, name="X")  # create global logo
    assert logo_path.exists()
    logo_path.unlink(missing_ok=True)


def test_create_locale_jpg_logo(create_dept, create_logos):
    dept1, dept2, dept3 = create_dept
    path = Path(f"{RESOURCES_DIR}/logo_C.jpg")
    stream = path.open("rb")
    logo_path = Path(scu.SCODOC_LOGOS_DIR).joinpath(f"logos_{dept1.id}", "logo_Y.jpg")
    assert not logo_path.exists()
    write_logo(stream, name="Y", dept_id=dept1.id)  # create global logo
    assert logo_path.exists()
    logo_path.unlink(missing_ok=True)


def test_create_jpg_instead_of_png_logo(create_dept, create_logos):
    # action
    logo = Logo("D")  # create global logo (replace logo_D.png)
    path = Path(f"{RESOURCES_DIR}/logo_C.jpg")
    stream = path.open("rb")
    logo.create(stream)
    # test
    created = Path(f"{scu.SCODOC_LOGOS_DIR}/logo_D.jpg")
    removed = Path(f"{scu.SCODOC_LOGOS_DIR}/logo_D.png")
    # file system check
    assert created.exists()
    assert not removed.exists()
    # logo check
    logo = find_logo("D")
    assert logo is not None
    assert logo.filepath == f"{scu.SCODOC_LOGOS_DIR}/logo_D.jpg"  # created.absolute()
    # restore initial state
    original = Path(f"{RESOURCES_DIR}/logo_D.png")
    copy(original, removed)
    created.unlink(missing_ok=True)


def test_list_logo(create_dept, create_logos):
    # test only existence of copied logos. We assumes that they are OK
    dept1, dept2, dept3 = create_dept
    logos = list_logos()
    assert set(logos.keys()) == {dept1.id, dept2.id, None}
    assert {"A", "C", "D", "E", "F", "header", "footer"}.issubset(
        set(logos[None].keys())
    )
    rt = logos.get(dept1.id, None)
    assert rt is not None
    assert {"A", "B"}.issubset(set(rt.keys()))
    info = logos.get(dept2.id, None)
    assert info is not None
    assert {"A"}.issubset(set(rt.keys()))
    gea = logos.get(dept3.id, None)
    assert gea is None
