"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.default = void 0;

function _isEmpty() {
  const data = _interopRequireDefault(require("lodash/isEmpty"));

  _isEmpty = function () {
    return data;
  };

  return data;
}

function _pickBy() {
  const data = _interopRequireDefault(require("lodash/pickBy"));

  _pickBy = function () {
    return data;
  };

  return data;
}

function _get() {
  const data = _interopRequireDefault(require("lodash/get"));

  _get = function () {
    return data;
  };

  return data;
}

function _xdl() {
  const data = require("@expo/xdl");

  _xdl = function () {
    return data;
  };

  return data;
}

function _BaseBuilder() {
  const data = _interopRequireDefault(require("../BaseBuilder"));

  _BaseBuilder = function () {
    return data;
  };

  return data;
}

function _constants() {
  const data = require("../constants");

  _constants = function () {
    return data;
  };

  return data;
}

function constants() {
  const data = _interopRequireWildcard(require("./credentials/constants"));

  constants = function () {
    return data;
  };

  return data;
}

function utils() {
  const data = _interopRequireWildcard(require("../utils"));

  utils = function () {
    return data;
  };

  return data;
}

function credentials() {
  const data = _interopRequireWildcard(require("./credentials"));

  credentials = function () {
    return data;
  };

  return data;
}

function apple() {
  const data = _interopRequireWildcard(require("./appleApi"));

  apple = function () {
    return data;
  };

  return data;
}

function _image() {
  const data = require("./utils/image");

  _image = function () {
    return data;
  };

  return data;
}

function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) { var desc = Object.defineProperty && Object.getOwnPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : {}; if (desc.get || desc.set) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } } newObj.default = obj; return newObj; } }

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

class IOSBuilder extends _BaseBuilder().default {
  async run() {
    await this.validateProject();
    await this.checkForBuildInProgress();

    if (this.options.type === 'archive') {
      await this.prepareCredentials();
    }

    const publishedExpIds = await this.ensureProjectIsPublished();

    if (!this.options.publicUrl) {
      await this.checkStatusBeforeBuild();
    }

    await this.build(publishedExpIds);
  }

  async validateProject() {
    const bundleIdentifier = (0, _get().default)(this.manifest, 'ios.bundleIdentifier');
    const sdkVersion = this.manifest.sdkVersion;
    await this.validateIcon();

    if (!bundleIdentifier) {
      throw new (_xdl().XDLError)('INVALID_OPTIONS', `Your project must have a bundleIdentifier set in app.json.
See https://docs.expo.io/versions/latest/distribution/building-standalone-apps/#2-configure-appjson`);
    }

    await utils().checkIfSdkIsSupported(sdkVersion, _constants().PLATFORMS.IOS);
  }

  async getAppleCtx({
    bundleIdentifier,
    username,
    experienceName
  }) {
    if (!this.appleCtx) {
      await apple().setup();
      const authData = await apple().authenticate(this.options);
      this.appleCtx = { ...authData,
        bundleIdentifier,
        username,
        experienceName
      };
    }

    return this.appleCtx;
  }

  async prepareCredentials() {
    const username = this.manifest.owner || this.user.username;
    const projectMetadata = {
      username,
      experienceName: `@${username}/${this.manifest.slug}`,
      sdkVersion: this.manifest.sdkVersion,
      bundleIdentifier: (0, _get().default)(this.manifest, 'ios.bundleIdentifier')
    };
    await this.clearAndRevokeCredentialsIfRequested(projectMetadata);
    const existingCredentials = await credentials().fetch(projectMetadata);
    const missingCredentials = credentials().determineMissingCredentials(existingCredentials);

    if (missingCredentials) {
      await this.produceMissingCredentials(projectMetadata, missingCredentials);
    }
  }

  async clearAndRevokeCredentialsIfRequested(projectMetadata) {
    const {
      clearCredentials,
      clearDistCert,
      clearPushKey,
      clearPushCert,
      clearProvisioningProfile
    } = this.options;
    const shouldClearAnything = clearCredentials || clearDistCert || clearPushKey || clearPushCert || clearProvisioningProfile;

    if (shouldClearAnything) {
      const credsToClear = await this.clearCredentialsIfRequested(projectMetadata);

      if (credsToClear && this.options.revokeCredentials) {
        await credentials().revoke((await this.getAppleCtx(projectMetadata)), Object.keys(credsToClear));
      }
    }
  }

  async clearCredentialsIfRequested(projectMetadata) {
    const credsToClear = this.determineCredentialsToClear();

    if (credsToClear) {
      await credentials().clear(projectMetadata, credsToClear);
    }

    return credsToClear;
  }

  determineCredentialsToClear() {
    const {
      clearCredentials,
      clearDistCert,
      clearPushKey,
      clearPushCert,
      clearProvisioningProfile
    } = this.options;
    const credsToClearAll = {
      distributionCert: Boolean(clearCredentials || clearDistCert),
      pushKey: Boolean(clearCredentials || clearPushKey),
      // TODO: backward compatibility, remove when all users migrate to push keys
      pushCert: Boolean(clearCredentials || clearPushCert),
      provisioningProfile: Boolean(clearCredentials || clearProvisioningProfile)
    };
    const credsToClear = (0, _pickBy().default)(credsToClearAll);
    return (0, _isEmpty().default)(credsToClear) ? null : credsToClear;
  }

  async produceMissingCredentials(projectMetadata, missingCredentials) {
    const appleCtx = await this.getAppleCtx(projectMetadata);
    const metadata = {};

    if (missingCredentials.includes(constants().PROVISIONING_PROFILE) && !missingCredentials.includes(constants().DISTRIBUTION_CERT)) {
      // we need to get distribution certificate serial number
      metadata.distCertSerialNumber = await credentials().getDistributionCertSerialNumber(projectMetadata);
    }

    const {
      userCredentialsIds,
      credentials: userProvidedCredentials,
      toGenerate,
      metadata: metadataFromPrompt
    } = await credentials().prompt(appleCtx, this.options, missingCredentials);
    Object.assign(metadata, metadataFromPrompt);
    const generatedCredentials = await credentials().generate(appleCtx, toGenerate, metadata);
    const newCredentials = { ...userProvidedCredentials,
      ...generatedCredentials,
      teamId: appleCtx.team.id
    };
    await credentials().update(projectMetadata, newCredentials, userCredentialsIds);
  }

  async ensureProjectIsPublished() {
    if (this.options.publicUrl) {
      return undefined;
    } else {
      return await this.ensureReleaseExists(_constants().PLATFORMS.IOS);
    }
  }

  platform() {
    return _constants().PLATFORMS.IOS;
  } // validates whether the icon doesn't have transparency


  async validateIcon() {
    try {
      const icon = (0, _get().default)(this.manifest, 'ios.icon', this.manifest.icon);
      await (0, _image().ensurePNGIsNotTransparent)(icon);
    } catch (err) {
      if (err instanceof _xdl().XDLError) {
        throw err;
      } else {// something weird happened, let's assume the icon is correct
      }
    }
  }

}

var _default = IOSBuilder;
exports.default = _default;
//# sourceMappingURL=../../../__sourcemaps__/commands/build/ios/IOSBuilder.js.map