use super::*;

impl PostgresRegistry {
    pub async fn create_yaml_import_job(
        &self,
        request: CreateYamlImportJobRequest<'_>,
    ) -> Result<(), RegistryError> {
        sqlx::query(
            "insert into yaml_import_jobs (
                id,
                source_sample_id,
                status,
                format_version,
                mode,
                result_operation_id,
                result_version,
                error_text,
                created_at,
                finished_at
             ) values (
                $1, $2, $3, $4, $5, null, null, null, $6::timestamptz, null
             )",
        )
        .bind(request.id.as_str())
        .bind(request.source_sample_id.map(|value| value.as_str()))
        .bind(serialize_enum_text(
            &YamlImportJobStatus::Pending,
            "status",
        )?)
        .bind(request.format_version)
        .bind(serialize_enum_text(&request.mode, "mode")?)
        .bind(request.created_at)
        .execute(&self.pool)
        .await?;

        Ok(())
    }

    pub async fn finish_yaml_import_job(
        &self,
        job_id: &YamlImportJobId,
        completion: &YamlImportJobCompletion,
    ) -> Result<(), RegistryError> {
        let result = sqlx::query(
            "update yaml_import_jobs
                set status = $2,
                    result_operation_id = $3,
                    result_version = $4,
                    error_text = $5,
                    finished_at = $6::timestamptz
              where id = $1",
        )
        .bind(job_id.as_str())
        .bind(serialize_enum_text(&completion.status, "status")?)
        .bind(
            completion
                .result_operation_id
                .as_ref()
                .map(|value| value.as_str()),
        )
        .bind(completion.result_version.map(to_db_version))
        .bind(completion.error_text.as_deref())
        .bind(completion.finished_at)
        .execute(&self.pool)
        .await?;

        if result.rows_affected() == 0 {
            return Err(RegistryError::YamlImportJobNotFound {
                job_id: job_id.as_str().to_owned(),
            });
        }

        Ok(())
    }

    pub async fn get_yaml_import_job(
        &self,
        job_id: &YamlImportJobId,
    ) -> Result<Option<YamlImportJob>, RegistryError> {
        let row = sqlx::query(
            "select
                id,
                source_sample_id,
                status,
                format_version,
                mode,
                result_operation_id,
                result_version,
                error_text,
                created_at,
                finished_at
             from yaml_import_jobs
             where id = $1",
        )
        .bind(job_id.as_str())
        .fetch_optional(&self.pool)
        .await?;

        row.as_ref().map(map_yaml_import_job).transpose()
    }
}
