text: "use strict";
  /** @module @twilio-labs/serverless-api/dist/api */
  var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
      function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
      return new (P || (P = Promise))(function (resolve, reject) {
          function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
          function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
          function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
          step((generator = generator.apply(thisArg, _arguments || [])).next());
      });
  };
  var __importDefault = (this && this.__importDefault) || function (mod) {
      return (mod && mod.__esModule) ? mod : { "default": mod };
  };
  Object.defineProperty(exports, "__esModule", { value: true });
  const { promisfy } = require('util');
  const debug_1 = __importDefault(require("debug"));
  const form_data_1 = __importDefault(require("form-data"));
  const content_type_1 = require("../utils/content-type");
  const pagination_1 = require("./utils/pagination");
  const log = debug_1.default('twilio-serverless-api:assets');
  /**
   * Calls the API to create a new Asset Resource
   *
   * @param  {string} name friendly name of the resource
   * @param  {string} serviceSid service to register asset under
   * @param  {GotClient} client API client
   * @returns {Promise<AssetApiResource>}
   */
  function createAssetResource(name, serviceSid, client) {
      return __awaiter(this, void 0, void 0, function* () {
          try {
              const resp = yield client.post(`/Services/${serviceSid}/Assets`, {
                  form: true,
                  body: {
                      FriendlyName: name,
                  },
              });
              return resp.body;
          }
          catch (err) {
              log('%O', err);
              throw new Error(`Failed to create "${name}" asset`);
          }
      });
  }
  /**
   * Calls the API to retrieve a list of all assets
   *
   * @param {string} serviceSid service to look for assets
   * @param {GotClient} client API client
   * @returns {Promise<AssetApiResource[]>}
   */
  function listAssetResources(serviceSid, client) {
      return __awaiter(this, void 0, void 0, function* () {
          try {
              return pagination_1.getPaginatedResource(client, `/Services/${serviceSid}/Assets`);
          }
          catch (err) {
              log('%O', err);
              throw err;
          }
      });
  }
  exports.listAssetResources = listAssetResources;
  /**
   * Given a list of resources it will first check which assets already exists
   * and create the remaining ones.
   *
   * @param  {FileInfo[]} assets
   * @param  {string} serviceSid
   * @param  {GotClient} client
   * @returns {Promise<AssetResource[]>}
   */
  function getOrCreateAssetResources(assets, serviceSid, client) {
      return __awaiter(this, void 0, void 0, function* () {
          const output = [];
          const existingAssets = yield listAssetResources(serviceSid, client);
          const assetsToCreate = [];
          assets.forEach(asset => {
              const existingAsset = existingAssets.find(x => asset.name === x.friendly_name);
              if (!existingAsset) {
                  assetsToCreate.push(asset);
              }
              else {
                  output.push(Object.assign(Object.assign({}, asset), { sid: existingAsset.sid }));
              }
          });
          const createdAssets = yield Promise.all(assetsToCreate.map((asset) => __awaiter(this, void 0, void 0, function* () {
              const newAsset = yield createAssetResource(asset.name, serviceSid, client);
              return Object.assign(Object.assign({}, asset), { sid: newAsset.sid });
          })));
          return [...output, ...createdAssets];
      });
  }
  exports.getOrCreateAssetResources = getOrCreateAssetResources;
  /**
   * Given an asset it will create a new version instance for it
   *
   * @param  {AssetResource} asset the one to create a new version for
   * @param  {string} serviceSid the service to create the asset version for
   * @param  {GotClient} client API client
   * @returns {Promise<VersionResource>}
   */
  function createAssetVersion(asset, serviceSid, client) {
      return __awaiter(this, void 0, void 0, function* () {
          try {
              const contentType = content_type_1.getContentType(asset.content, asset.filePath || asset.name);
              log('Uploading asset via form data with content-type "%s"', contentType);
              const contentOpts = {
                  filename: asset.name,
                  contentType: contentType,
              };
              const form = new form_data_1.default();
              form.append('Path', asset.path);
              form.append('Visibility', asset.access);
              form.append('Content', asset.content, contentOpts);
              const resp = yield client.post(`/Services/${serviceSid}/Assets/${asset.sid}/Versions`, {
                  baseUrl: 'https://serverless-upload.twilio.com/v1',
                  body: form,
                  //@ts-ignore
                  json: false,
              });
              return JSON.parse(resp.body);
          }
          catch (err) {
              log('%O', err);
              throw new Error('Failed to upload Asset');
          }
      });
  }
  /**
   * Uploads a given asset by creating a new version and uploading the content there
   *
   * @export
   * @param {AssetResource} asset The asset to upload
   * @param {string} serviceSid The service to upload it to
   * @param {GotClient} client The API client
   * @returns {Promise<Sid>}
   */
  function uploadAsset(asset, serviceSid, client) {
      return __awaiter(this, void 0, void 0, function* () {
          const version = yield createAssetVersion(asset, serviceSid, client);
          return version.sid;
      });
  }
  exports.uploadAsset = uploadAsset;
  