text: /*! firebase-admin v8.12.0 */
  "use strict";
  /*!
   * Copyright 2020 Google Inc.
   *
   * Licensed under the Apache License, Version 2.0 (the "License");
   * you may not use this file except in compliance with the License.
   * You may obtain a copy of the License at
   *
   *   http://www.apache.org/licenses/LICENSE-2.0
   *
   * Unless required by applicable law or agreed to in writing, software
   * distributed under the License is distributed on an "AS IS" BASIS,
   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   * See the License for the specific language governing permissions and
   * limitations under the License.
   */
  Object.defineProperty(exports, "__esModule", { value: true });
  var machine_learning_api_client_1 = require("./machine-learning-api-client");
  var error_1 = require("../utils/error");
  var validator = require("../utils/validator");
  var machine_learning_utils_1 = require("./machine-learning-utils");
  var deep_copy_1 = require("../utils/deep-copy");
  var utils = require("../utils");
  /**
   * Internals of an ML instance.
   */
  var MachineLearningInternals = /** @class */ (function () {
      function MachineLearningInternals() {
      }
      /**
       * Deletes the service and its associated resources.
       *
       * @return {Promise<void>} An empty Promise that will be resolved when the
       *     service is deleted.
       */
      MachineLearningInternals.prototype.delete = function () {
          // There are no resources to clean up.
          return Promise.resolve();
      };
      return MachineLearningInternals;
  }());
  /**
   * The Firebase Machine Learning class
   */
  var MachineLearning = /** @class */ (function () {
      /**
       * @param {FirebaseApp} app The app for this ML service.
       * @constructor
       */
      function MachineLearning(app) {
          this.INTERNAL = new MachineLearningInternals();
          if (!validator.isNonNullObject(app) || !('options' in app)) {
              throw new error_1.FirebaseError({
                  code: 'machine-learning/invalid-argument',
                  message: 'First argument passed to admin.machineLearning() must be a ' +
                      'valid Firebase app instance.',
              });
          }
          this.appInternal = app;
          this.client = new machine_learning_api_client_1.MachineLearningApiClient(app);
      }
      Object.defineProperty(MachineLearning.prototype, "app", {
          /**
           * Returns the app associated with this ML instance.
           *
           * @return {FirebaseApp} The app associated with this ML instance.
           */
          get: function () {
              return this.appInternal;
          },
          enumerable: true,
          configurable: true
      });
      /**
       * Creates a model in Firebase ML.
       *
       * @param {ModelOptions} model The model to create.
       *
       * @return {Promise<Model>} A Promise fulfilled with the created model.
       */
      MachineLearning.prototype.createModel = function (model) {
          var _this = this;
          return this.signUrlIfPresent(model)
              .then(function (modelContent) { return _this.client.createModel(modelContent); })
              .then(function (operation) { return handleOperation(operation); });
      };
      /**
       * Updates a model in Firebase ML.
       *
       * @param {string} modelId The id of the model to update.
       * @param {ModelOptions} model The model fields to update.
       *
       * @return {Promise<Model>} A Promise fulfilled with the updated model.
       */
      MachineLearning.prototype.updateModel = function (modelId, model) {
          var _this = this;
          var updateMask = utils.generateUpdateMask(model);
          return this.signUrlIfPresent(model)
              .then(function (modelContent) { return _this.client.updateModel(modelId, modelContent, updateMask); })
              .then(function (operation) { return handleOperation(operation); });
      };
      /**
       * Publishes a model in Firebase ML.
       *
       * @param {string} modelId The id of the model to publish.
       *
       * @return {Promise<Model>} A Promise fulfilled with the published model.
       */
      MachineLearning.prototype.publishModel = function (modelId) {
          return this.setPublishStatus(modelId, true);
      };
      /**
       * Unpublishes a model in Firebase ML.
       *
       * @param {string} modelId The id of the model to unpublish.
       *
       * @return {Promise<Model>} A Promise fulfilled with the unpublished model.
       */
      MachineLearning.prototype.unpublishModel = function (modelId) {
          return this.setPublishStatus(modelId, false);
      };
      /**
       * Gets a model from Firebase ML.
       *
       * @param {string} modelId The id of the model to get.
       *
       * @return {Promise<Model>} A Promise fulfilled with the unpublished model.
       */
      MachineLearning.prototype.getModel = function (modelId) {
          return this.client.getModel(modelId)
              .then(function (modelResponse) { return new Model(modelResponse); });
      };
      /**
       * Lists models from Firebase ML.
       *
       * @param {ListModelsOptions} options The listing options.
       *
       * @return {Promise<{models: Model[], pageToken?: string}>} A promise that
       *     resolves with the current (filtered) list of models and the next page
       *     token. For the last page, an empty list of models and no page token are
       *     returned.
       */
      MachineLearning.prototype.listModels = function (options) {
          if (options === void 0) { options = {}; }
          return this.client.listModels(options)
              .then(function (resp) {
              if (!validator.isNonNullObject(resp)) {
                  throw new machine_learning_utils_1.FirebaseMachineLearningError('invalid-argument', "Invalid ListModels response: " + JSON.stringify(resp));
              }
              var models = [];
              if (resp.models) {
                  models = resp.models.map(function (rs) { return new Model(rs); });
              }
              var result = { models: models };
              if (resp.nextPageToken) {
                  result.pageToken = resp.nextPageToken;
              }
              return result;
          });
      };
      /**
       * Deletes a model from Firebase ML.
       *
       * @param {string} modelId The id of the model to delete.
       */
      MachineLearning.prototype.deleteModel = function (modelId) {
          return this.client.deleteModel(modelId);
      };
      MachineLearning.prototype.setPublishStatus = function (modelId, publish) {
          var updateMask = ['state.published'];
          var options = { state: { published: publish } };
          return this.client.updateModel(modelId, options, updateMask)
              .then(function (operation) { return handleOperation(operation); });
      };
      MachineLearning.prototype.signUrlIfPresent = function (options) {
          var _a;
          var modelOptions = deep_copy_1.deepCopy(options);
          if ((_a = modelOptions.tfliteModel) === null || _a === void 0 ? void 0 : _a.gcsTfliteUri) {
              return this.signUrl(modelOptions.tfliteModel.gcsTfliteUri)
                  .then(function (uri) {
                  modelOptions.tfliteModel.gcsTfliteUri = uri;
                  return modelOptions;
              })
                  .catch(function (err) {
                  throw new machine_learning_utils_1.FirebaseMachineLearningError('internal-error', "Error during signing upload url: " + err.message);
              });
          }
          return Promise.resolve(modelOptions);
      };
      MachineLearning.prototype.signUrl = function (unsignedUrl) {
          var MINUTES_IN_MILLIS = 60 * 1000;
          var URL_VALID_DURATION = 10 * MINUTES_IN_MILLIS;
          var gcsRegex = /^gs:\/\/([a-z0-9_.-]{3,63})\/(.+)$/;
          var matches = gcsRegex.exec(unsignedUrl);
          if (!matches) {
              throw new machine_learning_utils_1.FirebaseMachineLearningError('invalid-argument', "Invalid unsigned url: " + unsignedUrl);
          }
          var bucketName = matches[1];
          var blobName = matches[2];
          var bucket = this.appInternal.storage().bucket(bucketName);
          var blob = bucket.file(blobName);
          return blob.getSignedUrl({
              action: 'read',
              expires: Date.now() + URL_VALID_DURATION,
          }).then(function (signUrl) { return signUrl[0]; });
      };
      return MachineLearning;
  }());
  exports.MachineLearning = MachineLearning;
  /**
   * A Firebase ML Model output object.
   */
  var Model = /** @class */ (function () {
      function Model(model) {
          var _a, _b, _c, _d, _e;
          if (!validator.isNonNullObject(model) ||
              !validator.isNonEmptyString(model.name) ||
              !validator.isNonEmptyString(model.createTime) ||
              !validator.isNonEmptyString(model.updateTime) ||
              !validator.isNonEmptyString(model.displayName) ||
              !validator.isNonEmptyString(model.etag)) {
              throw new machine_learning_utils_1.FirebaseMachineLearningError('invalid-server-response', "Invalid Model response: " + JSON.stringify(model));
          }
          this.modelId = extractModelId(model.name);
          this.displayName = model.displayName;
          this.tags = model.tags || [];
          this.createTime = new Date(model.createTime).toUTCString();
          this.updateTime = new Date(model.updateTime).toUTCString();
          if ((_b = (_a = model.state) === null || _a === void 0 ? void 0 : _a.validationError) === null || _b === void 0 ? void 0 : _b.message) {
              this.validationError = (_d = (_c = model.state) === null || _c === void 0 ? void 0 : _c.validationError) === null || _d === void 0 ? void 0 : _d.message;
          }
          this.published = ((_e = model.state) === null || _e === void 0 ? void 0 : _e.published) || false;
          this.etag = model.etag;
          if (model.modelHash) {
              this.modelHash = model.modelHash;
          }
          if (model.tfliteModel) {
              this.tfliteModel = {
                  gcsTfliteUri: model.tfliteModel.gcsTfliteUri,
                  sizeBytes: model.tfliteModel.sizeBytes,
              };
          }
      }
      Object.defineProperty(Model.prototype, "locked", {
          get: function () {
              // Backend does not currently return locked models.
              // This will likely change in future.
              return false;
          },
          enumerable: true,
          configurable: true
      });
      /* eslint-disable-next-line @typescript-eslint/no-unused-vars */
      Model.prototype.waitForUnlocked = function (maxTimeSeconds) {
          // Backend does not currently return locked models.
          // This will likely change in future.
          return Promise.resolve();
      };
      return Model;
  }());
  exports.Model = Model;
  function extractModelId(resourceName) {
      return resourceName.split('/').pop();
  }
  function handleOperation(op) {
      // Backend currently does not return operations that are not done.
      if (op.done) {
          // Done operations must have either a response or an error.
          if (op.response) {
              return new Model(op.response);
          }
          else if (op.error) {
              throw machine_learning_utils_1.FirebaseMachineLearningError.fromOperationError(op.error.code, op.error.message);
          }
      }
      throw new machine_learning_utils_1.FirebaseMachineLearningError('invalid-server-response', "Invalid Operation response: " + JSON.stringify(op));
  }
  