<?PHP
/**
 * Provides functions for easily logging updates to the main noda DB tables.
 *
 * @author Joshua Ramon Enslin <joshua@museum-digital.de>
 */
declare(strict_types = 1);

/**
 * Provides functions for easily logging updates to the main noda DB tables.
 */
final class NodaLogEdit {
    public const ACTION_WHITELIST = [
        'insert',
        'update',
        'merge',
        'delete',
    ];

    public const SECTION_WHITELIST = [
        'base',
        'addition',
        'noda_link',
        'name_variant',
        'logged_import_concordances',
        'research_note',
        'related',
        'superordinate',
        'subordinate',
        'synonym',
        'synchronize',
        'status',
        'translation',
        'group',
        'note',
    ];

    /**
     * Checks if a provided action is in the whitelist of allowed actions.
     * Throws an exception if that is not the case.
     *
     * @param string $action The action to validate.
     *
     * @return void
     */
    private static function validateAction(string $action):void {

        if (!in_array($action, self::ACTION_WHITELIST, true)) {
            throw new MDpageParameterNotFromListException("Invalid action. The following actions are available: " . implode(', ', self::ACTION_WHITELIST));
        }

    }

    /**
     * Checks if a provided section is in the whitelist of allowed sections.
     * Throws an exception if that is not the case.
     *
     * @param string $section The section to validate.
     *
     * @return void
     */
    private static function validateSection(string $section):void {

        if (!in_array($section, self::SECTION_WHITELIST, true)) {
            throw new MDpageParameterNotFromListException("Invalid section. The following sections are available: " . implode(', ', self::SECTION_WHITELIST));
        }

    }

    /**
     * Logs edits to a tag.
     *
     * @param MDMysqli $mysqli_noda DB connection.
     * @param integer  $tag_id      Tag ID.
     * @param string   $tool_name   Name of the tool used.
     * @param string   $user_name   Name of the user.
     * @param string   $action      Action to enter.
     * @param string   $section     Section that has been updated.
     *
     * @return void
     */
    public static function logTagEdit(MDMysqli $mysqli_noda, int $tag_id, string $tool_name, string $user_name, string $action, string $section):void {

        self::validateAction($action);
        self::validateSection($section);

        $insertStmt = $mysqli_noda->do_prepare("INSERT INTO `tag_edit_log`
            (`tag_id`, `tool_name`, `user_name`, `timestamp`, `action`, `section`)
            VALUES
            (?, ?, ?, NOW(), ?, ?)");

        $insertStmt->bind_param("issss", $tag_id, $tool_name, $user_name, $action, $section);
        $insertStmt->execute();
        $insertStmt->close();

        // Update the main tag table, except for edits to the base,
        // as these have built-in updating and updating in this case
        // would be superfluous.
        if ($section !== 'base') {

            $updateStmt = $mysqli_noda->do_prepare("UPDATE `tag`
                SET `tag_erfasst_am` = NOW(),
                    `tag_erfasst_von` = ?
                WHERE `tag_id` = ?");
            $updateStmt->bind_param("si", $user_name, $tag_id);
            $updateStmt->execute();
            $updateStmt->close();

        }

    }

    /**
     * Logs edits to a actor.
     *
     * @param MDMysqli $mysqli_noda DB connection.
     * @param integer  $persinst_id Actor ID.
     * @param string   $tool_name   Name of the tool used.
     * @param string   $user_name   Name of the user.
     * @param string   $action      Action to enter.
     * @param string   $section     Section that has been updated.
     *
     * @return void
     */
    public static function logPersinstEdit(MDMysqli $mysqli_noda, int $persinst_id, string $tool_name, string $user_name, string $action, string $section):void {

        self::validateAction($action);
        self::validateSection($section);

        $insertStmt = $mysqli_noda->do_prepare("INSERT INTO `persinst_edit_log`
            (`persinst_id`, `tool_name`, `user_name`, `timestamp`, `action`, `section`)
            VALUES
            (?, ?, ?, NOW(), ?, ?)");

        $insertStmt->bind_param("issss", $persinst_id, $tool_name, $user_name, $action, $section);
        $insertStmt->execute();
        $insertStmt->close();

    }

    /**
     * Logs edits to a time entries.
     *
     * @param MDMysqli $mysqli_noda DB connection.
     * @param integer  $zeit_id     Time ID.
     * @param string   $tool_name   Name of the tool used.
     * @param string   $user_name   Name of the user.
     * @param string   $action      Action to enter.
     * @param string   $section     Section that has been updated.
     *
     * @return void
     */
    public static function logTimeEdit(MDMysqli $mysqli_noda, int $zeit_id, string $tool_name, string $user_name, string $action, string $section):void {

        self::validateAction($action);
        self::validateSection($section);

        $insertStmt = $mysqli_noda->do_prepare("INSERT INTO `zeiten_edit_log`
            (`zeit_id`, `tool_name`, `user_name`, `timestamp`, `action`, `section`)
            VALUES
            (?, ?, ?, NOW(), ?, ?)");

        $insertStmt->bind_param("issss", $zeit_id, $tool_name, $user_name, $action, $section);
        $insertStmt->execute();
        $insertStmt->close();

    }

    /**
     * Logs edits to a place entries.
     *
     * @param MDMysqli $mysqli_noda DB connection.
     * @param integer  $ort_id      Place ID.
     * @param string   $tool_name   Name of the tool used.
     * @param string   $user_name   Name of the user.
     * @param string   $action      Action to enter.
     * @param string   $section     Section that has been updated.
     *
     * @return void
     */
    public static function logPlaceEdit(MDMysqli $mysqli_noda, int $ort_id, string $tool_name, string $user_name, string $action, string $section):void {

        self::validateAction($action);
        self::validateSection($section);

        $insertStmt = $mysqli_noda->do_prepare("INSERT INTO `orte_edit_log`
            (`ort_id`, `tool_name`, `user_name`, `timestamp`, `action`, `section`)
            VALUES
            (?, ?, ?, NOW(), ?, ?)");

        $insertStmt->bind_param("issss", $ort_id, $tool_name, $user_name, $action, $section);
        $insertStmt->execute();
        $insertStmt->close();

        // Update the main tag table, except for edits to the base,
        // as these have built-in updating and updating in this case
        // would be superfluous.
        if ($section !== 'base') {

            $updateStmt = $mysqli_noda->do_prepare("UPDATE `orte`
                SET `ort_erfasst_am` = NOW(),
                    `ort_erfasst_von` = ?
                WHERE `ort_id` = ?");
            $updateStmt->bind_param("si", $user_name, $ort_id);
            $updateStmt->execute();
            $updateStmt->close();

        }

    }
}
