""" Methods for PhotosDB to add Photos face info 
"""

from .._constants import _DB_TABLE_NAMES, _PHOTOS_4_VERSION
from ..sqlite_utils import sqlite_open_ro
from ..unicode import normalize_unicode
from .photosdb_utils import get_db_version

"""
    This module should be imported in the class defintion of PhotosDB in photosdb.py
    Do not import this module directly
    This module adds the following method to PhotosDB:
        _process_faceinfo: process photo face info 

    The following data structures are added to PhotosDB
        self._db_faceinfo_pk: {pk: {faceinfo}}
        self._db_faceinfo_uuid: {photo uuid: [face pk]}
        self._db_faceinfo_person: {person_pk: [face_pk]}
"""


def _process_faceinfo(self):
    """Process face information"""

    self._db_faceinfo_pk = {}
    self._db_faceinfo_uuid = {}
    self._db_faceinfo_person = {}

    if self._db_version <= _PHOTOS_4_VERSION:
        _process_faceinfo_4(self)
    else:
        _process_faceinfo_5(self)


def _process_faceinfo_4(photosdb):
    """Process face information for Photos 4 databases

    Args:
        photosdb: an OSXPhotosDB instance
    """
    db = photosdb._tmp_db

    (conn, cursor) = sqlite_open_ro(db)

    result = cursor.execute(
        """
        SELECT
        RKFace.modelId,
        RKVersion.uuid, 
        RKFace.uuid,
        RKPerson.name,
        RKFace.isInTrash,
        RKFace.personId,
        RKFace.imageModelId, 
        RKFace.sourceWidth,
        RKFace.sourceHeight, 
        RKFace.centerX,
        RKFace.centerY,
        RKFace.size,
        RKFace.leftEyeX, 
        RKFace.leftEyeY,
        RKFace.rightEyeX, 
        RKFace.rightEyeY, 
        RKFace.mouthX,
        RKFace.mouthY, 
        RKFace.hidden, 
        RKFace.manual, 
        RKFace.hasSmile, 
        RKFace.isLeftEyeClosed, 
        RKFace.isRightEyeClosed, 
        RKFace.poseRoll, 
        RKFace.poseYaw, 
        RKFace.posePitch, 
        RKFace.faceType,
        RKFace.qualityMeasure
        FROM
        RKFace
        JOIN RKPerson on RKPerson.modelId = RKFace.personId
        JOIN RKVersion on RKVersion.modelId = RKFace.imageModelId
        """
    )

    # 0     RKFace.modelId,
    # 1     RKVersion.uuid,
    # 2     RKFace.uuid,
    # 3     RKPerson.name,
    # 4     RKFace.isInTrash,
    # 5     RKFace.personId,
    # 6     RKFace.imageModelId,
    # 7     RKFace.sourceWidth,
    # 8     RKFace.sourceHeight,
    # 9     RKFace.centerX,
    # 10    RKFace.centerY,
    # 11    RKFace.size,
    # 12    RKFace.leftEyeX,
    # 13    RKFace.leftEyeY,
    # 14    RKFace.rightEyeX,
    # 15    RKFace.rightEyeY,
    # 16    RKFace.mouthX,
    # 17    RKFace.mouthY,
    # 18    RKFace.hidden,
    # 19    RKFace.manual,
    # 20    RKFace.hasSmile,
    # 21    RKFace.isLeftEyeClosed,
    # 22    RKFace.isRightEyeClosed,
    # 23    RKFace.poseRoll,
    # 24    RKFace.poseYaw,
    # 25    RKFace.posePitch,
    # 26    RKFace.faceType,
    # 27    RKFace.qualityMeasure

    for row in result:
        modelid = row[0]
        asset_uuid = row[1]
        person_id = row[5]
        face = {}
        face["pk"] = modelid
        face["asset_uuid"] = asset_uuid
        face["uuid"] = row[2]
        face["person"] = person_id
        face["fullname"] = normalize_unicode(row[3])
        face["sourcewidth"] = row[7]
        face["sourceheight"] = row[8]
        face["centerx"] = row[9]
        face["centery"] = row[10]
        face["size"] = row[11]
        face["lefteyex"] = row[12]
        face["lefteyey"] = row[13]
        face["righteyex"] = row[14]
        face["righteyey"] = row[15]
        face["mouthx"] = row[16]
        face["mouthy"] = row[17]
        face["hidden"] = row[18]
        face["manual"] = row[19]
        face["has_smile"] = row[20]
        face["left_eye_closed"] = row[21]
        face["right_eye_closed"] = row[22]
        face["roll"] = row[23]
        face["yaw"] = row[24]
        face["pitch"] = row[25]
        face["facetype"] = row[26]
        face["quality"] = row[27]

        # Photos 5+ only
        face["agetype"] = None
        face["eyemakeuptype"] = None
        face["eyestate"] = None
        face["facialhairtype"] = None
        face["gendertype"] = None
        face["glassestype"] = None
        face["haircolortype"] = None
        face["intrash"] = None
        face["lipmakeuptype"] = None
        face["smiletype"] = None
        face["masteridentifier"] = None

        photosdb._db_faceinfo_pk[modelid] = face

        try:
            photosdb._db_faceinfo_uuid[asset_uuid].append(modelid)
        except KeyError:
            photosdb._db_faceinfo_uuid[asset_uuid] = [modelid]

        try:
            photosdb._db_faceinfo_person[person_id].append(modelid)
        except KeyError:
            photosdb._db_faceinfo_person[person_id] = [modelid]

    conn.close()


def _process_faceinfo_5(photosdb):
    """Process face information for Photos 5 databases

    Args:
        photosdb: an OSXPhotosDB instance
    """

    db = photosdb._tmp_db

    asset_table = _DB_TABLE_NAMES[photosdb._photos_ver]["ASSET"]
    asset_fk = _DB_TABLE_NAMES[photosdb._photos_ver]["DETECTED_FACE_ASSET_FK"]
    person_fk = _DB_TABLE_NAMES[photosdb._photos_ver]["DETECTED_FACE_PERSON_FK"]

    (conn, cursor) = sqlite_open_ro(db)

    result = cursor.execute(
        f""" 
        SELECT
        ZDETECTEDFACE.Z_PK,
        {asset_table}.ZUUID,
        ZDETECTEDFACE.ZUUID,
        {person_fk},
        ZPERSON.ZFULLNAME,
        ZDETECTEDFACE.ZAGETYPE,
        NULL, -- ZDETECTEDFACE.ZBALDTYPE (Removed in Monterey)
        ZDETECTEDFACE.ZEYEMAKEUPTYPE,
        ZDETECTEDFACE.ZEYESSTATE,
        ZDETECTEDFACE.ZFACIALHAIRTYPE,
        ZDETECTEDFACE.ZGENDERTYPE,
        ZDETECTEDFACE.ZGLASSESTYPE,
        ZDETECTEDFACE.ZHAIRCOLORTYPE,
        ZDETECTEDFACE.ZHASSMILE,
        ZDETECTEDFACE.ZHIDDEN,
        ZDETECTEDFACE.ZISINTRASH,
        NULL, -- ZDETECTEDFACE.ZISLEFTEYECLOSED
        NULL, -- ZDETECTEDFACE.ZISRIGHTEYECLOSED
        ZDETECTEDFACE.ZLIPMAKEUPTYPE,
        ZDETECTEDFACE.ZMANUAL,
        ZDETECTEDFACE.ZQUALITYMEASURE,
        ZDETECTEDFACE.ZSMILETYPE,
        ZDETECTEDFACE.ZSOURCEHEIGHT,
        ZDETECTEDFACE.ZSOURCEWIDTH,
        ZDETECTEDFACE.ZBLURSCORE,
        ZDETECTEDFACE.ZCENTERX,
        ZDETECTEDFACE.ZCENTERY,
        NULL, -- ZDETECTEDFACE.ZLEFTEYEX,
        NULL, -- ZDETECTEDFACE.ZLEFTEYEY,
        NULL, -- ZDETECTEDFACE.ZMOUTHX,
        NULL, -- ZDETECTEDFACE.ZMOUTHY,
        ZDETECTEDFACE.ZPOSEYAW,
        ZDETECTEDFACE.ZQUALITY,
        NULL, -- ZDETECTEDFACE.ZRIGHTEYEX,
        NULL, -- ZDETECTEDFACE.ZRIGHTEYEY,
        ZDETECTEDFACE.ZROLL,
        ZDETECTEDFACE.ZSIZE,
        NULL, -- ZDETECTEDFACE.ZYAW,
        ZDETECTEDFACE.ZMASTERIDENTIFIER
        FROM ZDETECTEDFACE
        JOIN {asset_table} ON {asset_table}.Z_PK = {asset_fk}
        JOIN ZPERSON ON ZPERSON.Z_PK = {person_fk};
        """
    )

    # 0    ZDETECTEDFACE.Z_PK
    # 1    ZGENERICASSET.ZUUID,
    # 2    ZDETECTEDFACE.ZUUID,
    # 3    ZDETECTEDFACE.ZPERSON,
    # 4    ZPERSON.ZFULLNAME,
    # 5    ZDETECTEDFACE.ZAGETYPE,
    # 6    NULL -- ZDETECTEDFACE.ZBALDTYPE,  (Not available on Monterey)
    # 7    ZDETECTEDFACE.ZEYEMAKEUPTYPE,
    # 8    ZDETECTEDFACE.ZEYESSTATE,
    # 9    ZDETECTEDFACE.ZFACIALHAIRTYPE,
    # 10   ZDETECTEDFACE.ZGENDERTYPE,
    # 11   ZDETECTEDFACE.ZGLASSESTYPE,
    # 12   ZDETECTEDFACE.ZHAIRCOLORTYPE,
    # 13   ZDETECTEDFACE.ZHASSMILE,
    # 14   ZDETECTEDFACE.ZHIDDEN,
    # 15   ZDETECTEDFACE.ZISINTRASH,
    # 16   NULL -- ZDETECTEDFACE.ZISLEFTEYECLOSED,
    # 17   NULL -- ZDETECTEDFACE.ZISRIGHTEYECLOSED,
    # 18   ZDETECTEDFACE.ZLIPMAKEUPTYPE,
    # 19   ZDETECTEDFACE.ZMANUAL,
    # 20   ZDETECTEDFACE.ZQUALITYMEASURE,
    # 21   ZDETECTEDFACE.ZSMILETYPE,
    # 22   ZDETECTEDFACE.ZSOURCEHEIGHT,
    # 23   ZDETECTEDFACE.ZSOURCEWIDTH,
    # 24   ZDETECTEDFACE.ZBLURSCORE,
    # 25   ZDETECTEDFACE.ZCENTERX,
    # 26   ZDETECTEDFACE.ZCENTERY,
    # 27   NULL -- ZDETECTEDFACE.ZLEFTEYEX, (Not available on Ventura)
    # 28   NULL -- ZDETECTEDFACE.ZLEFTEYEY, (Not available on Ventura)
    # 29   NULL -- ZDETECTEDFACE.ZMOUTHX, (Not available on Ventura)
    # 30   NULL -- ZDETECTEDFACE.ZMOUTHY, (Not available on Ventura)
    # 31   ZDETECTEDFACE.ZPOSEYAW,
    # 32   ZDETECTEDFACE.ZQUALITY,
    # 33   NULL -- ZDETECTEDFACE.ZRIGHTEYEX, (Not available on Ventura)
    # 34   NULL -- ZDETECTEDFACE.ZRIGHTEYEY, (Not available on Ventura)
    # 35   ZDETECTEDFACE.ZROLL,
    # 36   ZDETECTEDFACE.ZSIZE,
    # 37   NULL -- ZDETECTEDFACE.ZYAW, (Not available on Ventura)
    # 38   ZDETECTEDFACE.ZMASTERIDENTIFIER

    for row in result:
        pk = row[0]
        asset_uuid = row[1]
        person_pk = row[3]
        face = {}
        face["pk"] = pk
        face["asset_uuid"] = asset_uuid
        face["uuid"] = row[2]
        face["person"] = person_pk
        face["fullname"] = normalize_unicode(row[4])
        face["agetype"] = row[5]
        face["eyemakeuptype"] = row[7]
        face["eyestate"] = row[8]
        face["facialhairtype"] = row[9]
        face["gendertype"] = row[10]
        face["glassestype"] = row[11]
        face["haircolortype"] = row[12]
        face["has_smile"] = row[13]
        face["hidden"] = row[14]
        face["intrash"] = row[15]
        face["left_eye_closed"] = row[16]
        face["right_eye_closed"] = row[17]
        face["lipmakeuptype"] = row[18]
        face["manual"] = row[19]
        face["smiletype"] = row[21]
        face["sourceheight"] = row[22]
        face["sourcewidth"] = row[23]
        face["facetype"] = None  # Photos 4 only
        face["centerx"] = row[25]
        face["centery"] = row[26]
        face["lefteyex"] = row[27]
        face["lefteyey"] = row[28]
        face["mouthx"] = row[29]
        face["mouthy"] = row[30]
        face["quality"] = row[32]
        face["righteyex"] = row[33]
        face["righteyey"] = row[34]
        face["roll"] = row[35]
        face["size"] = row[36]
        face["masteridentifier"] = row[38]
        face["yaw"] = (
            0  # Photos 4 only (this is in Photos 5-7, but dropped in Ventura so just don't support it)
        )
        face["pitch"] = 0  # not defined in Photos 5

        photosdb._db_faceinfo_pk[pk] = face

        try:
            photosdb._db_faceinfo_uuid[asset_uuid].append(pk)
        except KeyError:
            photosdb._db_faceinfo_uuid[asset_uuid] = [pk]

        try:
            photosdb._db_faceinfo_person[person_pk].append(pk)
        except KeyError:
            photosdb._db_faceinfo_person[person_pk] = [pk]

    conn.close()
