"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.default = void 0;
var _core = require("@credo-ts/core");
var _pool = require("@credo-ts/indy-vdr/build/pool");
var _reactHooks = require("@credo-ts/react-hooks");
var _reactNative = require("@credo-ts/react-native");
var _indyVdrShared = require("@hyperledger/indy-vdr-shared");
var _react = require("react");
var _reactNativeConfig = require("react-native-config");
var _reactNativeFs = require("react-native-fs");
var _containerApi = require("../container-api");
var _auth = require("../contexts/auth");
var _store = require("../contexts/reducers/store");
var _store2 = require("../contexts/store");
var _error = require("../types/error");
var _agent = require("../utils/agent");
var _migration = require("../utils/migration");
const useInitializeAgent = () => {
  const {
    agent,
    setAgent
  } = (0, _reactHooks.useAgent)();
  const [store, dispatch] = (0, _store2.useStore)();
  const {
    walletSecret
  } = (0, _auth.useAuth)();
  const [cacheSchemas, cacheCredDefs, logger, indyLedgers] = (0, _containerApi.useServices)([_containerApi.TOKENS.CACHE_SCHEMAS, _containerApi.TOKENS.CACHE_CRED_DEFS, _containerApi.TOKENS.UTIL_LOGGER, _containerApi.TOKENS.UTIL_LEDGERS]);
  const restartExistingAgent = (0, _react.useCallback)(async () => {
    if (!(walletSecret !== null && walletSecret !== void 0 && walletSecret.id) || !walletSecret.key || !agent) {
      return;
    }
    logger.info('Agent already initialized, restarting...');
    try {
      await agent.wallet.open({
        id: walletSecret.id,
        key: walletSecret.key
      });
      logger.info('Opened agent wallet');
    } catch (error) {
      // Credo does not use error codes but this will be in the
      // the error message if the wallet is already open.
      const catchPhrase = 'instance already opened';
      if (error instanceof _core.WalletError && error.message.includes(catchPhrase)) {
        logger.warn('Wallet already open, nothing to do');
      } else {
        logger.error('Error opening existing wallet:', error);
        throw new _error.BifoldError('Wallet Service', 'There was a problem unlocking the wallet.', error.message, 1047);
      }
    }
    await agent.mediationRecipient.initiateMessagePickup();
  }, [agent, walletSecret, logger]);
  const createNewAgent = (0, _react.useCallback)(async () => {
    if (!(walletSecret !== null && walletSecret !== void 0 && walletSecret.id) || !walletSecret.key) {
      return;
    }
    logger.info('No agent initialized, creating a new one');
    const newAgent = new _core.Agent({
      config: {
        label: store.preferences.walletName || 'Aries Bifold',
        walletConfig: {
          id: walletSecret.id,
          key: walletSecret.key
        },
        logger,
        autoUpdateStorageOnStartup: true
      },
      dependencies: _reactNative.agentDependencies,
      modules: (0, _agent.getAgentModules)({
        indyNetworks: indyLedgers,
        mediatorInvitationUrl: _reactNativeConfig.Config.MEDIATOR_URL,
        txnCache: {
          capacity: 1000,
          expiryOffsetMs: 1000 * 60 * 60 * 24 * 7,
          path: _reactNativeFs.CachesDirectoryPath + '/txn-cache'
        }
      })
    });
    const wsTransport = new _core.WsOutboundTransport();
    const httpTransport = new _core.HttpOutboundTransport();
    newAgent.registerOutboundTransport(wsTransport);
    newAgent.registerOutboundTransport(httpTransport);
    return newAgent;
  }, [walletSecret, store.preferences.walletName, logger, indyLedgers]);
  const migrateIfRequired = (0, _react.useCallback)(async newAgent => {
    if (!(walletSecret !== null && walletSecret !== void 0 && walletSecret.id) || !walletSecret.key) {
      return;
    }

    // If we haven't migrated to Aries Askar yet, we need to do this before we initialize the agent.
    if (!store.migration.didMigrateToAskar) {
      newAgent.config.logger.debug('Agent not updated to Aries Askar, updating...');
      await (0, _migration.migrateToAskar)(walletSecret.id, walletSecret.key, newAgent);
      newAgent.config.logger.debug('Successfully finished updating agent to Aries Askar');
      // Store that we migrated to askar.
      dispatch({
        type: _store.DispatchAction.DID_MIGRATE_TO_ASKAR
      });
    }
  }, [walletSecret, store.migration.didMigrateToAskar, dispatch]);
  const warmUpCache = (0, _react.useCallback)(async newAgent => {
    const poolService = newAgent.dependencyManager.resolve(_pool.IndyVdrPoolService);
    cacheCredDefs.forEach(async ({
      did,
      id
    }) => {
      const pool = await poolService.getPoolForDid(newAgent.context, did);
      const credDefRequest = new _indyVdrShared.GetCredentialDefinitionRequest({
        credentialDefinitionId: id
      });
      await pool.pool.submitRequest(credDefRequest);
    });
    cacheSchemas.forEach(async ({
      did,
      id
    }) => {
      const pool = await poolService.getPoolForDid(newAgent.context, did);
      const schemaRequest = new _indyVdrShared.GetSchemaRequest({
        schemaId: id
      });
      await pool.pool.submitRequest(schemaRequest);
    });
  }, [cacheCredDefs, cacheSchemas]);
  const initializeAgent = (0, _react.useCallback)(async () => {
    if (!(walletSecret !== null && walletSecret !== void 0 && walletSecret.id) || !walletSecret.key) {
      return;
    }
    if (agent) {
      await restartExistingAgent();
      return agent;
    }
    const newAgent = await createNewAgent();
    if (!newAgent) {
      return;
    }
    await migrateIfRequired(newAgent);
    await newAgent.initialize();
    await (0, _agent.createLinkSecretIfRequired)(newAgent);
    await warmUpCache(newAgent);
    setAgent(newAgent);
    return newAgent;
  }, [agent, setAgent, walletSecret, restartExistingAgent, createNewAgent, migrateIfRequired, warmUpCache]);
  return {
    initializeAgent
  };
};
var _default = exports.default = useInitializeAgent;
//# sourceMappingURL=initialize-agent.js.map