<?PHP
/**
 * This file handles the insertion of new entries to a noda DB in batch.
 *
 * @file
 * @author Joshua Ramon Enslin <joshua@museum-digital.de>
 */
declare(strict_types = 1);

/**
 * This file handles the insertion of new entries to a noda DB in batch.
 */
final class NodaBatchInserter {
    /**
     * Inserts a batch of actor translations.
     *
     * @param MDMysqli                                                                                      $mysqli_noda DB connection.
     * @param array<array{persinst_id: int, lang: string, name: string, description: string, link: string}> $toInsert    List of actor translations to enter.
     *
     * @return void
     */
    public static function insertPersinstTranslations(MDMysqli $mysqli_noda, array $toInsert):void {

        $mysqli_noda->autocommit(false);
        $insertStmt = $mysqli_noda->do_prepare("CALL `nodaInsertPersinstTranslation`(?, ?, ?, ?, ?)");

        foreach ($toInsert as $values) {

            try {
                $insertStmt->bind_param("issss", $values['persinst_id'],
                    $values['lang'],
                    $values['name'],
                    $values['description'],
                    $values['link']);
                $insertStmt->execute();
            }
            catch (MDMysqliInvalidEncodingError $e) {
            }

        }

        $mysqli_noda->commit();
        $insertStmt->close();

        $mysqli_noda->autocommit(true);

    }

    /**
     * Inserts a batch of place translations.
     *
     * @param MDMysqli                                                                                 $mysqli_noda DB connection.
     * @param array<array{ort_id: int, lang: string, name: string, description: string, link: string}> $toInsert    List of place translations to enter.
     *
     * @return void
     */
    public static function insertPlaceTranslations(MDMysqli $mysqli_noda, array $toInsert):void {

        $mysqli_noda->autocommit(false);
        $insertStmt = $mysqli_noda->do_prepare("CALL `nodaInsertOrtTranslation`(?, ?, ?, ?, ?)");

        foreach ($toInsert as $values) {

            try {
                $insertStmt->bind_param("issss", $values['ort_id'],
                    $values['lang'],
                    $values['name'],
                    $values['description'],
                    $values['link']);
                $insertStmt->execute();
            }
            catch (MDMysqliInvalidEncodingError $e) {
            }

        }

        $mysqli_noda->commit();
        $insertStmt->close();

        $mysqli_noda->autocommit(true);

    }

    /**
     * Inserts a batch of tag translations.
     *
     * @param MDMysqli                                                                                 $mysqli_noda DB connection.
     * @param array<array{tag_id: int, lang: string, name: string, description: string, link: string}> $toInsert    List of tag translations to enter.
     *
     * @return void
     */
    public static function insertTagTranslations(MDMysqli $mysqli_noda, array $toInsert):void {

        $mysqli_noda->autocommit(false);
        $insertStmt = $mysqli_noda->do_prepare("CALL nodaInsertTagTranslation(?, ?, ?, ?, ?)");

        foreach ($toInsert as $values) {

            try {
                $insertStmt->bind_param("issss", $values['tag_id'],
                    $values['lang'],
                    $values['name'],
                    $values['description'],
                    $values['link']);
                $insertStmt->execute();
            }
            catch (MDMysqliInvalidEncodingError $e) {
            }

        }

        $mysqli_noda->commit();
        $insertStmt->close();

        $mysqli_noda->autocommit(true);

    }

    /**
     * Adds links to norm data repositories for an actor.
     *
     * @param MDMysqli                    $mysqli_noda DB connection.
     * @param integer                     $persinst_id Actor ID.
     * @param non-empty-array<MDNodaLink> $noda_links  Entries to link.
     * @param string                      $user_name   Name of the current user.
     *
     * @return void
     */
    public static function linkNodaForPersinst(MDMysqli $mysqli_noda, int $persinst_id, array $noda_links, string $user_name):void {

        $mysqli_noda->autocommit(false);

        $insertNodaLinkStmt = $mysqli_noda->do_prepare("INSERT INTO `noda`
            (`persinst_id`, `noda_source`, `noda_nrinsource`, `noda_link`, `noda_erfasst_von`)
            VALUES
            (?, ?, ?, ?, ?)
            ON DUPLICATE KEY UPDATE `noda_erfasst_am` = NOW()");

        foreach ($noda_links as $nodaLink) {

            $noda_source = $nodaLink->source->toDbName();
            $noda_id = $nodaLink->id;
            $noda_link_url = $nodaLink->getEntityLink();

            if (!in_array($noda_source, MDNodaRepositoriesSet::REPOSITORIES_ACTOR, true)) {
                continue;
            }

            $insertNodaLinkStmt->bind_param("issss", $persinst_id, $noda_source, $noda_id, $noda_link_url, $user_name);
            $insertNodaLinkStmt->execute();

        }

        $insertNodaLinkStmt->close();
        unset($insertNodaLinkStmt);

        $mysqli_noda->commit();
        $mysqli_noda->autocommit(true);

    }

    /**
     * Adds links to norm data repositories for a place.
     *
     * @param MDMysqli                    $mysqli_noda DB connection.
     * @param integer                     $ort_id      Place ID.
     * @param non-empty-array<MDNodaLink> $noda_links  Entries to link.
     * @param string                      $user_name   Name of the current user.
     *
     * @return void
     */
    public static function linkNodaForPlace(MDMysqli $mysqli_noda, int $ort_id, array $noda_links, string $user_name):void {

        $mysqli_noda->autocommit(false);

        $insertNodaLinkStmt = $mysqli_noda->do_prepare("INSERT INTO `noda_orte`
            (`ort_id`, `noda_source`, `noda_nrinsource`, `noda_link`, `noda_erfasst_von`)
            VALUES
            (?, ?, ?, ?, ?)
            ON DUPLICATE KEY UPDATE `noda_erfasst_am` = NOW()");

        foreach ($noda_links as $nodaLink) {

            $noda_source = $nodaLink->source->toDbName();
            $noda_id = $nodaLink->id;
            $noda_link_url = $nodaLink->getEntityLink();

            if (!in_array($noda_source, MDNodaRepositoriesSet::REPOSITORIES_PLACE, true)) {
                continue;
            }

            $insertNodaLinkStmt->bind_param("issss", $ort_id, $noda_source, $noda_id, $noda_link_url, $user_name);
            $insertNodaLinkStmt->execute();

        }

        $insertNodaLinkStmt->close();
        unset($insertNodaLinkStmt);

        $mysqli_noda->commit();
        $mysqli_noda->autocommit(true);

    }

    /**
     * Adds links to norm data repositories for a tag.
     *
     * @param MDMysqli                    $mysqli_noda DB connection.
     * @param integer                     $tag_id      Tag ID.
     * @param non-empty-array<MDNodaLink> $noda_links  Entries to link.
     * @param string                      $user_name   Name of the current user.
     *
     * @return void
     */
    public static function linkNodaForTag(MDMysqli $mysqli_noda, int $tag_id, array $noda_links, string $user_name):void {

        $mysqli_noda->autocommit(false);

        $insertNodaLinkStmt = $mysqli_noda->do_prepare("INSERT INTO `noda_tag`
            (`tag_id`, `noda_source`, `noda_nrinsource`, `noda_link`, `noda_erfasst_von`)
            VALUES
            (?, ?, ?, ?, ?)
            ON DUPLICATE KEY UPDATE `noda_erfasst_am` = NOW()");

        foreach ($noda_links as $nodaLink) {

            $noda_source = $nodaLink->source->toDbName();
            $noda_id = $nodaLink->id;
            $noda_link_url = $nodaLink->getEntityLink();

            if (!in_array($noda_source, MDNodaRepositoriesSet::REPOSITORIES_TAG, true)) {
                continue;
            }

            $insertNodaLinkStmt->bind_param("issss", $tag_id, $noda_source, $noda_id, $noda_link_url, $user_name);
            $insertNodaLinkStmt->execute();

        }

        $insertNodaLinkStmt->close();
        unset($insertNodaLinkStmt);

        $mysqli_noda->commit();
        $mysqli_noda->autocommit(true);

    }
}
