<?PHP
/**
 * Contains a class for getting linked entities for given vocabulary data.
 *
 * @author Joshua Ramon Enslin <joshua@museum-digital.de>
 */
declare(strict_types = 1);

/**
 * Contains a class for getting linked entities for given vocabulary data.
 */
final class NodaLinkedEntityGetter {
    /**
     * Returns a list of norm data repository links for an actor.
     *
     * @param MDMysqli $mysqli_noda DB connection.
     * @param integer  $persinst_id ID of the actor to get synonyms for.
     *
     * @return array<MDNodaLink>
     */
    public static function listPersinstNodaLinks(MDMysqli $mysqli_noda, int $persinst_id):array {

        $result = $mysqli_noda->query_by_stmt("SELECT `noda_source`, `noda_nrinsource`
            FROM `noda`
            WHERE `persinst_id` = ?", "i", $persinst_id);

        $output = [];
        if ($result->num_rows !== 0) {
            while ($cur = $result->fetch_row()) {
                $output[] = new MDNodaLink(MDNodaRepository::fromString($cur[0]), $cur[1]);
            }
        }
        $result->close();

        return $output;

    }

    /**
     * Returns a list of norm data repository links for a place.
     *
     * @param MDMysqli $mysqli_noda DB connection.
     * @param integer  $place_id    ID of the place to get synonyms for.
     *
     * @return array<MDNodaLink>
     */
    public static function listPlaceNodaLinks(MDMysqli $mysqli_noda, int $place_id):array {

        $result = $mysqli_noda->query_by_stmt("SELECT `noda_source`, `noda_nrinsource`
            FROM `noda_orte`
            WHERE `ort_id` = ?", "i", $place_id);

        $output = [];
        if ($result->num_rows !== 0) {
            while ($cur = $result->fetch_row()) {
                $output[] = new MDNodaLink(MDNodaRepository::fromString($cur[0]), $cur[1]);
            }
        }
        $result->close();

        return $output;

    }

    /**
     * Returns a list of norm data repository links for a tag.
     *
     * @param MDMysqli $mysqli_noda DB connection.
     * @param integer  $tag_id      ID of the tag to get synonyms for.
     *
     * @return array<MDNodaLink>
     */
    public static function listTagNodaLinks(MDMysqli $mysqli_noda, int $tag_id):array {

        $result = $mysqli_noda->query_by_stmt("SELECT `noda_source`, `noda_nrinsource`
            FROM `noda_tag`
            WHERE `tag_id` = ?", "i", $tag_id);

        $output = [];
        if ($result->num_rows !== 0) {
            while ($cur = $result->fetch_row()) {
                $output[] = new MDNodaLink(MDNodaRepository::fromString($cur[0]), $cur[1]);
            }
        }
        $result->close();

        return $output;

    }

    /**
     * Returns synonyms of a place.
     *
     * @param MDMysqli $mysqli_noda DB connection.
     * @param integer  $place_id    ID of the place to get synonyms for.
     *
     * @return array<int>
     */
    public static function listPlaceSynonyms(MDMysqli $mysqli_noda, int $place_id):array {

        $result = $mysqli_noda->do_read_query("SELECT `ort_syn_main`, `ort_syn_sub`
            FROM `ort_syn`
            WHERE `ort_syn_main` = " . $place_id . "
                OR `ort_syn_sub` = " . $place_id . "
            LIMIT 1");

        $output = [];
        while ($cur = $result->fetch_row()) {
            // Use keys to prevent duplicates
            $id1 = (int)$cur[0];
            $id2 = (int)$cur[1];
            if ($id1 !== $place_id) $output[$id1] = true;
            if ($id2 !== $place_id) $output[$id2] = true;
        }
        $result->close();

        return array_keys($output);

    }

    /**
     * Returns the main synonym of a tag (or the tag ID itself, if there are
     * no synonyms).
     *
     * @param MDMysqli $mysqli_noda DB connection.
     * @param integer  $tag_id      ID of the tag to check.
     *
     * @return integer
     */
    public static function getMainTagSynonymId(MDMysqli $mysqli_noda, int $tag_id):int {

        $result = $mysqli_noda->query_by_stmt("SELECT `tag_syn_main`
            FROM `tag_syn`
            WHERE `tag_syn_sub` = ?
            LIMIT 1", "i", $tag_id);

        if ($cur = $result->fetch_row()) {
            $output = MD_STD_IN::sanitize_id($cur[0]);
        }
        else {
            $output = $tag_id;
        }
        $result->close();

        return $output;

    }

    /**
     * Returns the main synonym of a place (or the place ID itself, if there are
     * no synonyms).
     *
     * @param MDMysqli $mysqli_noda DB connection.
     * @param integer  $place_id    ID of the place to check.
     *
     * @return integer
     */
    public static function getMainPlaceSynonymId(MDMysqli $mysqli_noda, int $place_id):int {

        $result = $mysqli_noda->query_by_stmt("SELECT `ort_syn_main`
            FROM `ort_syn`
            WHERE `ort_syn_sub` = ?
            LIMIT 1", "i", $place_id);

        if ($cur = $result->fetch_row()) {
            $output = MD_STD_IN::sanitize_id($cur[0]);
        }
        else {
            $output = $place_id;
        }
        $result->close();

        return $output;

    }
}
