/// <reference types="./google-cloud.d.ts" />
(function (global, factory) {
    typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, require('node:util'), require('@google-cloud/cloudbuild'), require('google-auth-library'), require('@google-cloud/run')) :
    typeof define === 'function' && define.amd ? define(['exports', 'node:util', '@google-cloud/cloudbuild', 'google-auth-library', '@google-cloud/run'], factory) :
    (global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global.DevKit = {}, global["node:util"], global["@google-cloud/cloudbuild"], global["google-auth-library"], global["@google-cloud/run"]));
})(this, (function (exports, node_util, cloudbuild, googleAuthLibrary, run) { 'use strict';

    // todo: put these into `Substitution variables`
    // Refs: https://github.com/TexteaInc/PyDataFront
    const funixEntryPoint = 'python3 -m pydatafront main';
    const deployRegion = 'us-central1'; // iowa
    const gcrHostname = 'gcr.io';
    const platform = 'managed';
    const createFunixBuildSteps = (repoId, cloudRunServiceName, _config) => {
        const dockerImageUrl = `${gcrHostname}/$PROJECT_ID/${repoId}/${cloudRunServiceName}:$COMMIT_SHA`;
        return {
            tags: [
                'redstone-auto-deploy',
                cloudRunServiceName
            ],
            images: [
                // push to Google Container Registry
                dockerImageUrl
            ],
            steps: [
                // todo(himself65): check whether user already have `requirements.txt` before step 1?
                // step 1: build Funix
                {
                    name: 'gcr.io/k8s-skaffold/pack',
                    id: 'build-pack',
                    entrypoint: 'pack',
                    env: [
                        `GOOGLE_ENTRYPOINT=${funixEntryPoint}`
                    ],
                    args: [
                        'build',
                        dockerImageUrl,
                        '--builder=gcr.io/buildpacks/builder:v1',
                        '--network=cloudbuild',
                        '--path=.',
                        '--env=GOOGLE_ENTRYPOINT'
                    ]
                },
                // step 2: push to Google Container Registry
                //  Does this conflict with 'build.images'?
                {
                    name: 'gcr.io/cloud-builders/docker',
                    args: [
                        'push',
                        dockerImageUrl
                    ]
                },
                // step 3: push to Google Cloud Run by service name
                {
                    name: 'gcr.io/google.com/cloudsdktool/cloud-sdk:slim',
                    id: 'deploy',
                    entrypoint: 'gcloud',
                    args: [
                        'run',
                        'services',
                        'update',
                        cloudRunServiceName,
                        `--platform=${platform}`,
                        `--image=${dockerImageUrl}`,
                        `--region=${deployRegion}`
                    ]
                }
            ]
        };
    };

    // region generate unique name that won't make conflict with each user
    const createAuth = (info) => {
        return new googleAuthLibrary.GoogleAuth({
            credentials: info
        });
    };
    // google cloud build images only accept a lowercase name
    const getProjectId = (owner, repoName) => `${owner}-${repoName}`.toLowerCase();
    const getCloudBuildTriggerName = (owner, repoName) => `${owner}-${repoName}`.toLowerCase();
    // google cloud run only accept a lowercase name
    const getCloudRunServiceName = (owner, repoName) => `${owner}-${repoName}`.toLowerCase();

    const logger$1 = node_util.debuglog('textea-dev-kit');
    function createCloudBuild(config) {
        const cloudBuildClient = new cloudbuild.CloudBuildClient({
            projectId: config.projectId,
            auth: config.auth ? createAuth(config.auth) : undefined
        });
        logger$1('create cloud build client success.');
        logger$1('project id: %s', config.projectId);
        const apis = {
            _client: cloudBuildClient,
            createBuildTrigger: async (owner, repoName) => {
                const triggerName = getCloudBuildTriggerName(owner, repoName);
                const serviceName = getCloudRunServiceName(owner, repoName);
                // tip: let it crash if build trigger already exist
                const [trigger] = await cloudBuildClient.createBuildTrigger({
                    projectId: config.projectId,
                    trigger: {
                        name: triggerName,
                        description: 'Build And Deploy to Cloud Run managed by Redstone API',
                        github: {
                            owner,
                            name: repoName,
                            push: {
                                branch: '^main'
                            }
                        },
                        build: createFunixBuildSteps(getProjectId(owner, repoName), serviceName)
                    }
                });
                return trigger;
            },
            runBuildTrigger: async (owner, repoName) => {
                const triggerName = getCloudBuildTriggerName(owner, repoName);
                const [operation] = await cloudBuildClient.runBuildTrigger({
                    projectId: config.projectId,
                    triggerId: triggerName,
                    source: {
                        branchName: 'main'
                    }
                });
                return operation;
            }
        };
        Object.freeze(apis);
        return apis;
    }

    const logger = node_util.debuglog('textea-dev-kit');
    function createCloudRun(config) {
        const cloudRunClient = new run.v2.ServicesClient({
            projectId: config.projectId,
            auth: config.auth ? createAuth(config.auth) : undefined
        });
        logger('create cloud run client success');
        const apis = {
            _client: cloudRunClient,
            getCloudRunService: async (owner, repoName) => {
                const serviceName = getCloudRunServiceName(owner, repoName);
                const name = `projects/${config.projectId}/locations/us-central1/services/${serviceName}`;
                const [detail] = await cloudRunClient.getService({
                    name
                });
                if (detail !== null) {
                    logger('get service success');
                }
                return detail;
            },
            getCloudRunServiceURL: async (owner, repoName) => {
                const { uri } = await apis.getCloudRunService(owner, repoName);
                logger('get service url: %s', uri);
                return uri;
            },
            createCloudRun: async (owner, repoName) => {
                const serviceName = getCloudRunServiceName(owner, repoName);
                // tip: let it crash if build trigger already exist
                const parent = `projects/${config.projectId}/locations/us-central1`;
                const resource = `${parent}/${serviceName}`;
                await cloudRunClient.createService({
                    parent,
                    serviceId: serviceName,
                    service: {
                        ingress: 1,
                        description: 'Created by redstone',
                        template: {
                            containers: [
                                {
                                    // use hello world image in the first run
                                    image: 'us-docker.pkg.dev/cloudrun/container/hello:latest'
                                }
                            ],
                            maxInstanceRequestConcurrency: 100,
                            timeout: {
                                seconds: 10
                            },
                            scaling: {
                                minInstanceCount: 0,
                                maxInstanceCount: 1
                            }
                        }
                    }
                });
                await cloudRunClient.setIamPolicy({
                    resource,
                    policy: {
                        bindings: [
                            {
                                role: 'roles/run.invoker',
                                members: [
                                    'allUsers'
                                ],
                                condition: null
                            }
                        ]
                    }
                });
            }
        };
        Object.freeze(apis);
        return apis;
    }

    exports.createAuth = createAuth;
    exports.createCloudBuild = createCloudBuild;
    exports.createCloudRun = createCloudRun;
    exports.createFunixBuildSteps = createFunixBuildSteps;
    exports.getCloudBuildTriggerName = getCloudBuildTriggerName;
    exports.getCloudRunServiceName = getCloudRunServiceName;
    exports.getProjectId = getProjectId;

    Object.defineProperty(exports, '__esModule', { value: true });

}));
//# sourceMappingURL=google-cloud.js.map
