import * as FetchHttpClient from "@effect/platform/FetchHttpClient";
import * as HttpApi from "@effect/platform/HttpApi";
import * as HttpApiClient from "@effect/platform/HttpApiClient";
import * as HttpApiEndpoint from "@effect/platform/HttpApiEndpoint";
import * as HttpApiError from "@effect/platform/HttpApiError";
import * as HttpApiGroup from "@effect/platform/HttpApiGroup";
import * as HttpApiSchema from "@effect/platform/HttpApiSchema";
import * as HttpClient from "@effect/platform/HttpClient";
import * as HttpClientRequest from "@effect/platform/HttpClientRequest";
import * as Context from "effect/Context";
import * as Effect from "effect/Effect";
import * as Layer from "effect/Layer";
import * as Schema from "effect/Schema";
import * as Model from "../Model.js";
import * as Error from "./Error.js";
/**
 * The dataset namespace parameter.
 */
const datasetNamespace = HttpApiSchema.param("namespace", Model.DatasetNamespace);
/**
 * The dataset name parameter.
 */
const datasetName = HttpApiSchema.param("name", Model.DatasetName);
/**
 * The dataset revision parameter (version, hash, "latest", or "dev").
 */
const datasetRevision = HttpApiSchema.param("revision", Schema.String);
/**
 * The job ID parameter (GET /jobs/{jobId}, DELETE /jobs/{jobId}, PUT /jobs/{jobId}/stop).
 */
const jobId = HttpApiSchema.param("jobId", Model.JobIdParam);
export class RegisterDatasetPayload extends Schema.Class("RegisterDatasetPayload")({
    namespace: Schema.String.pipe(Schema.propertySignature, Schema.fromKey("namespace")),
    name: Schema.String.pipe(Schema.propertySignature, Schema.fromKey("name")),
    version: Schema.optional(Schema.String).pipe(Schema.fromKey("version")),
    manifest: Model.DatasetManifest,
}) {
}
/**
 * The register dataset endpoint (POST /datasets).
 */
const registerDataset = HttpApiEndpoint.post("registerDataset") `/datasets`
    .addError(Error.InvalidPayloadFormat)
    .addError(Error.InvalidManifest)
    .addError(Error.ManifestValidationError)
    .addError(Error.UnsupportedDatasetKind)
    .addError(Error.ManifestRegistrationError)
    .addError(Error.ManifestLinkingError)
    .addError(Error.VersionTaggingError)
    .addError(Error.StoreError)
    .addError(Error.ManifestNotFound)
    .addSuccess(Schema.Void, { status: 201 })
    .setPayload(RegisterDatasetPayload);
export class GetDatasetsResponse extends Schema.Class("GetDatasetsResponse")({
    datasets: Schema.Array(Schema.Struct({
        namespace: Model.DatasetNamespace,
        name: Model.DatasetName,
        latestVersion: Model.DatasetVersion.pipe(Schema.optional, Schema.fromKey("latest_version")),
        versions: Schema.Array(Model.DatasetVersion),
    })),
}) {
}
/**
 * The get datasets endpoint (GET /datasets).
 */
const getDatasets = HttpApiEndpoint.get("getDatasets") `/datasets`
    .addError(Error.DatasetStoreError)
    .addError(Error.MetadataDbError)
    .addSuccess(GetDatasetsResponse);
export class GetDatasetVersionsResponse extends Schema.Class("GetDatasetVersionsResponse")({
    versions: Schema.Array(Model.DatasetVersion),
}) {
}
/**
 * The get dataset versions endpoint (GET /datasets/{namespace}/{name}/versions).
 */
const getDatasetVersions = HttpApiEndpoint.get("getDatasetVersions") `/datasets/${datasetNamespace}/${datasetName}/versions`
    .addError(Error.InvalidRequest)
    .addError(Error.DatasetStoreError)
    .addError(Error.MetadataDbError)
    .addSuccess(GetDatasetVersionsResponse);
export class GetDatasetVersionResponse extends Schema.Class("GetDatasetVersionResponse")({
    namespace: Model.DatasetNamespace,
    name: Model.DatasetName,
    revision: Model.DatasetRevision,
    manifestHash: Model.DatasetHash.pipe(Schema.propertySignature, Schema.fromKey("manifest_hash")),
    kind: Model.DatasetKind,
}) {
}
/**
 * The get dataset by revision endpoint (GET /datasets/{namespace}/{name}/versions/{revision}).
 */
const getDatasetVersion = HttpApiEndpoint.get("getDatasetVersion") `/datasets/${datasetNamespace}/${datasetName}/versions/${datasetRevision}`
    .addError(Error.InvalidRequest)
    .addError(Error.DatasetNotFound)
    .addError(Error.DatasetStoreError)
    .addError(Error.MetadataDbError)
    .addSuccess(GetDatasetVersionResponse);
export class DeployDatasetPayload extends Schema.Class("DeployRequest")({
    endBlock: Schema.optional(Schema.NullOr(Schema.String)).pipe(Schema.fromKey("end_block")),
    parallelism: Schema.optional(Schema.Number),
}) {
}
export class DeployDatasetResponse extends Schema.Class("DeployResponse")({
    jobId: Model.JobId.pipe(Schema.propertySignature, Schema.fromKey("job_id")),
}) {
}
/**
 * The deploy dataset endpoint (POST /datasets/{namespace}/{name}/versions/{revision}/deploy).
 */
const deployDataset = HttpApiEndpoint.post("deployDataset") `/datasets/${datasetNamespace}/${datasetName}/versions/${datasetRevision}/deploy`
    .addError(Error.InvalidRequest)
    .addError(Error.DatasetNotFound)
    .addError(Error.DatasetStoreError)
    .addError(Error.SchedulerError)
    .addError(Error.MetadataDbError)
    .addSuccess(DeployDatasetResponse, { status: 202 })
    .setPayload(DeployDatasetPayload);
/**
 * The get dataset manifest endpoint (GET /datasets/{namespace}/{name}/versions/{revision}/manifest).
 */
const getDatasetManifest = HttpApiEndpoint.get("getDatasetManifest") `/datasets/${datasetNamespace}/${datasetName}/versions/${datasetRevision}/manifest`
    .addError(Error.InvalidRequest)
    .addError(Error.DatasetNotFound)
    .addError(Error.DatasetStoreError)
    .addError(Error.MetadataDbError)
    .addSuccess(Model.DatasetManifest);
/**
 * The get job by ID endpoint (GET /jobs/{jobId}).
 */
const getJobById = HttpApiEndpoint.get("getJobById") `/jobs/${jobId}`
    .addError(Error.InvalidJobId)
    .addError(Error.JobNotFound)
    .addError(Error.MetadataDbError)
    .addSuccess(Model.JobInfo);
export class GetOutputSchemaPayload extends Schema.Class("SchemaRequest")({
    tables: Schema.Record({ key: Schema.String, value: Schema.String }),
    dependencies: Schema.Record({ key: Schema.String, value: Model.DatasetReferenceFromString }).pipe(Schema.optional),
    functions: Schema.Record({ key: Schema.String, value: Model.FunctionDefinition }).pipe(Schema.optional),
}) {
}
export class GetOutputSchemaResponse extends Schema.Class("SchemaResponse")({
    schemas: Schema.Record({ key: Schema.String, value: Model.TableSchemaWithNetworks }),
}) {
}
/**
 * The output schema endpoint (POST /schema).
 */
const getOutputSchema = HttpApiEndpoint.post("getOutputSchema") `/schema`
    .addError(Error.InvalidPayloadFormat)
    .addError(Error.EmptyTablesAndFunctions)
    .addError(Error.InvalidTableSql)
    .addError(Error.TableReferenceResolution)
    .addError(Error.FunctionReferenceResolution)
    .addError(Error.DependencyNotFound)
    .addError(Error.DependencyResolution)
    .addError(Error.CatalogQualifiedTable)
    .addError(Error.UnqualifiedTable)
    .addError(Error.InvalidTableName)
    .addError(Error.DatasetNotFound)
    .addError(Error.GetDatasetError)
    .addError(Error.EthCallUdfCreationError)
    .addError(Error.TableNotFoundInDataset)
    .addError(Error.FunctionNotFoundInDataset)
    .addError(Error.EthCallNotAvailable)
    .addError(Error.DependencyAliasNotFound)
    .addError(Error.SchemaInference)
    .addSuccess(GetOutputSchemaResponse)
    .setPayload(GetOutputSchemaPayload);
/**
 * The api group for the dataset endpoints.
 */
export class DatasetGroup extends HttpApiGroup.make("dataset")
    .add(registerDataset)
    .add(getDatasets)
    .add(getDatasetVersions)
    .add(getDatasetVersion)
    .add(deployDataset)
    .add(getDatasetManifest) {
}
/**
 * The api group for the job endpoints.
 */
export class JobGroup extends HttpApiGroup.make("job").add(getJobById) {
}
/**
 * The api group for the schema endpoints.
 */
export class SchemaGroup extends HttpApiGroup.make("schema").add(getOutputSchema) {
}
/**
 * The api definition for the admin api.
 */
export class Api extends HttpApi.make("admin")
    .add(DatasetGroup)
    .add(JobGroup)
    .add(SchemaGroup)
    .addError(HttpApiError.Forbidden)
    .addError(HttpApiError.Unauthorized) {
}
/**
 * Service definition for the admin api.
 */
export class Admin extends Context.Tag("Amp/Admin")() {
}
/**
 * Creates an admin api service instance.
 *
 * @param url - The url of the admin api service.
 * @returns An admin api service instance.
 */
export const make = Effect.fn(function* (url, options) {
    const client = yield* HttpApiClient.make(Api, {
        ...options,
        baseUrl: url,
    });
    const registerDataset = Effect.fn("registerDataset")(function* (namespace, name, manifest, version) {
        const request = client.dataset.registerDataset({
            payload: {
                namespace,
                name,
                manifest,
                version,
            },
        });
        const result = yield* request.pipe(Effect.catchTags({
            HttpApiDecodeError: Effect.die,
            ParseError: Effect.die,
        }));
        return result;
    });
    const getDatasetVersions = Effect.fn("getDatasetVersions")(function* (namespace, name) {
        const result = yield* client.dataset.getDatasetVersions({
            path: {
                namespace,
                name,
            },
        }).pipe(Effect.catchTags({
            HttpApiDecodeError: Effect.die,
            ParseError: Effect.die,
        }));
        return result;
    });
    const getDatasetVersion = Effect.fn("getDatasetVersion")(function* (namespace, name, revision) {
        const result = yield* client.dataset.getDatasetVersion({
            path: {
                namespace,
                name,
                revision,
            },
        }).pipe(Effect.catchTags({
            HttpApiDecodeError: Effect.die,
            ParseError: Effect.die,
        }));
        return result;
    });
    const deployDataset = Effect.fn("deployDataset")(function* (namespace, name, revision, options) {
        const result = yield* client.dataset.deployDataset({
            path: {
                namespace,
                name,
                revision,
            },
            payload: {
                endBlock: options?.endBlock,
                parallelism: options?.parallelism,
            },
        }).pipe(Effect.catchTags({
            HttpApiDecodeError: Effect.die,
            ParseError: Effect.die,
        }));
        return result;
    });
    const getDatasetManifest = Effect.fn("getDatasetManifest")(function* (namespace, name, revision) {
        const result = yield* client.dataset.getDatasetManifest({
            path: {
                namespace,
                name,
                revision,
            },
        }).pipe(Effect.catchTags({
            HttpApiDecodeError: Effect.die,
            ParseError: Effect.die,
        }));
        return result;
    });
    const getDatasets = Effect.fn("getDatasets")(function* () {
        const result = yield* client.dataset.getDatasets({}).pipe(Effect.catchTags({
            HttpApiDecodeError: Effect.die,
            ParseError: Effect.die,
        }));
        return result;
    });
    const getJobById = Effect.fn("getJobById")(function* (jobId) {
        const result = yield* client.job.getJobById({
            path: {
                jobId,
            },
        }).pipe(Effect.catchTags({
            HttpApiDecodeError: Effect.die,
            ParseError: Effect.die,
        }));
        return result;
    });
    const getOutputSchema = Effect.fn("getOutputSchema")(function* (request) {
        const result = yield* client.schema.getOutputSchema({
            payload: request,
        }).pipe(Effect.catchTags({
            ParseError: Effect.die,
            HttpApiDecodeError: Effect.die,
        }));
        return result;
    });
    return {
        registerDataset,
        getDatasets,
        getDatasetVersions,
        getDatasetVersion,
        deployDataset,
        getDatasetManifest,
        getJobById,
        getOutputSchema,
    };
});
/**
 * Creates a layer for the admin api service.
 *
 * @param url - The url of the admin api service.
 * @param token - The bearer token.
 * @returns A layer for the admin api service.
 */
export const layer = (url, token) => Effect.gen(function* () {
    const api = yield* make(url, {
        transformClient: token === undefined ? undefined : (client) => client.pipe(HttpClient.mapRequestInput(HttpClientRequest.setHeader("Authorization", `Bearer ${token}`))),
    });
    return api;
}).pipe(Layer.effect(Admin), Layer.provide(FetchHttpClient.layer));
//# sourceMappingURL=Admin.js.map