"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.DownloadKeystore = exports.UpdateFcmKey = exports.UpdateKeystore = exports.ExperienceView = void 0;

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

  _xdl = function () {
    return data;
  };

  return data;
}

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

  _get = function () {
    return data;
  };

  return data;
}

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

  _isEmpty = function () {
    return data;
  };

  return data;
}

function _chalk() {
  const data = _interopRequireDefault(require("chalk"));

  _chalk = function () {
    return data;
  };

  return data;
}

function _fsExtra() {
  const data = _interopRequireDefault(require("fs-extra"));

  _fsExtra = function () {
    return data;
  };

  return data;
}

function _prompt() {
  const data = _interopRequireDefault(require("../../prompt"));

  _prompt = function () {
    return data;
  };

  return data;
}

function _log() {
  const data = _interopRequireDefault(require("../../log"));

  _log = function () {
    return data;
  };

  return data;
}

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

  _credentials = function () {
    return data;
  };

  return data;
}

function _list() {
  const data = require("../actions/list");

  _list = function () {
    return data;
  };

  return data;
}

function _promptForCredentials() {
  const data = require("../actions/promptForCredentials");

  _promptForCredentials = function () {
    return data;
  };

  return data;
}

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

function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }

class ExperienceView {
  constructor(experience, credentials) {
    _defineProperty(this, "keystore", null);

    _defineProperty(this, "pushCredentials", null);

    _defineProperty(this, "shouldRefetch", true);

    this.experience = experience;

    if (credentials && credentials.experienceName) {
      this.shouldRefetch = false;
      this.experienceName = credentials.experienceName;
      this.keystore = credentials.keystore;
      this.pushCredentials = credentials.pushCredentials;
    }
  }

  async open(ctx) {
    if (this.shouldRefetch) {
      const appCredentials = await ctx.api.getAsync(`credentials/android/@${ctx.user.username}/${this.experience}`);
      this.experienceName = (0, _get().default)(appCredentials, 'experienceName');
      this.keystore = (0, _get().default)(appCredentials, 'keystore');
      this.pushCredentials = (0, _get().default)(appCredentials, 'pushCredentials');
    }

    if (!this.experienceName) {
      this.experienceName = `@${ctx.user.username}/${this.experience}`;
    }

    if ((0, _isEmpty().default)(this.keystore) && (0, _isEmpty().default)(this.pushCredentials)) {
      (0, _log().default)(`No credentials available for ${this.experience} experience.\n`);
    } else if (this.experienceName) {
      (0, _log().default)();
      await (0, _list().displayAndroidAppCredentials)({
        experienceName: this.experienceName,
        keystore: this.keystore,
        pushCredentials: this.pushCredentials
      });
      (0, _log().default)();
    }

    const {
      action
    } = await (0, _prompt().default)([{
      type: 'list',
      name: 'action',
      message: 'What do you want to do?',
      choices: [{
        value: 'update-keystore',
        name: 'Update Upload Keystore'
      }, {
        value: 'update-fcm-key',
        name: 'Update FCM Api Key'
      }, {
        value: 'fetch-keystore',
        name: 'Download Keystore from the Expo servers'
      }]
    }]);
    return this.handleAction(ctx, action);
  }

  handleAction(context, selected) {
    switch (selected) {
      case 'update-keystore':
        this.shouldRefetch = true;
        return new UpdateKeystore(this.experience);

      case 'update-fcm-key':
        this.shouldRefetch = true;
        return new UpdateFcmKey(this.experience);

      case 'fetch-keystore':
        return new DownloadKeystore(this.experience, this.keystore);

      case 'fetch-public-cert':
        return null;
    }

    return null;
  }

}

exports.ExperienceView = ExperienceView;

class UpdateKeystore {
  constructor(experience) {
    this.experience = experience;
  }

  async open(ctx) {
    const keystore = await this.provideOrGenerate(ctx);
    await ctx.api.putAsync(`credentials/android/keystore/@${ctx.user.username}/${this.experience}`, {
      keystore
    });
    (0, _log().default)(_chalk().default.green('Updated Keystore successfully'));
    return null;
  }

  async provideOrGenerate(ctx) {
    const providedKeystore = await (0, _promptForCredentials().askForUserProvided)(_credentials().keystoreSchema);

    if (providedKeystore) {
      return providedKeystore;
    }

    const tmpKeystoreName = `${this.experience}_tmp.jks`;

    try {
      if (await _fsExtra().default.pathExists(tmpKeystoreName)) {
        await _fsExtra().default.unlink(tmpKeystoreName);
      }

      const keystoreData = await _xdl().AndroidCredentials.generateUploadKeystore(tmpKeystoreName, '---------------', // TODO: add android package (it's not required)
      `@${ctx.user.username}/${this.experience}`);
      return { ...keystoreData,
        keystore: await _fsExtra().default.readFile(tmpKeystoreName, 'base64')
      };
    } catch (error) {
      _log().default.warn("If you don't provide your own Android Kkeystore, it will be generated on our servers durring next build");

      throw error;
    } finally {
      if (await _fsExtra().default.pathExists(tmpKeystoreName)) {
        await _fsExtra().default.unlink(tmpKeystoreName);
      }
    }
  }

}

exports.UpdateKeystore = UpdateKeystore;

class UpdateFcmKey {
  constructor(experience) {
    this.experience = experience;
  }

  async open(ctx) {
    const {
      fcmApiKey
    } = await (0, _prompt().default)([{
      type: 'input',
      name: 'fcmApiKey',
      message: 'FCM Api Key',
      validate: value => value.length > 0 || "FCM Api Key can't be empty"
    }]);
    await ctx.api.putAsync(`credentials/android/push/@${ctx.user.username}/${this.experience}`, {
      fcmApiKey
    });
    (0, _log().default)(_chalk().default.green('Updated successfully'));
    return null;
  }

}

exports.UpdateFcmKey = UpdateFcmKey;

class DownloadKeystore {
  constructor(experience, credentials = null) {
    this.credentials = credentials;
    this.experience = experience;
  }

  async open(ctx) {
    const keystoreName = `${this.experience}.bak.jks`;
    const {
      confirm
    } = await (0, _prompt().default)({
      type: 'confirm',
      name: 'confirm',
      message: 'Do you want to display the Android Keystore credentials?'
    });
    (0, _log().default)(_chalk().default.green(`Saving Keystore to ${keystoreName}`));
    await this.save(ctx, keystoreName, confirm);
    return null;
  }

  async fetch(ctx) {
    const credentials = await _xdl().ApiV2.clientForUser(ctx.user).getAsync(`credentials/android/@${ctx.manifest.owner || ctx.user.username}/${ctx.manifest.slug}`);

    if (credentials && credentials.keystore) {
      this.credentials = credentials.keystore;
    }
  }

  async save(ctx, keystorePath, shouldLog = false) {
    if (await _fsExtra().default.pathExists(keystorePath)) {
      await _fsExtra().default.unlink(keystorePath);
    }

    const {
      keystore,
      keystorePassword,
      keyAlias,
      keyPassword
    } = this.credentials || {};

    if (!keystore || !keystorePassword || !keyAlias || !keyPassword) {
      _log().default.warn('There is no valid Keystore defined for this app');

      return;
    }

    const storeBuf = Buffer.from(keystore, 'base64');
    await _fsExtra().default.writeFile(keystorePath, storeBuf);

    if (shouldLog) {
      (0, _log().default)(`Keystore credentials
  Keystore password: ${_chalk().default.bold(keystorePassword)}
  Key alias:         ${_chalk().default.bold(keyAlias)}
  Key password:      ${_chalk().default.bold(keyPassword)}

  Path to Keystore:  ${keystorePath}
      `);
    }
  }

}

exports.DownloadKeystore = DownloadKeystore;
//# sourceMappingURL=../../__sourcemaps__/credentials/views/AndroidCredentials.js.map