text: /*
   * 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.
   */
  
  'use strict';
  
  const { Certificate, ConnectionManager } = require('composer-common');
  const EmbeddedConnection = require('./embeddedconnection');
  const EmbeddedDataService = require('composer-runtime-embedded').EmbeddedDataService;
  const uuid = require('uuid');
  
  const IDENTITY_COLLECTION_ID = 'identities';
  
  /**
   * Base class representing a connection manager that establishes and manages
   * connections to one or more business networks.
   * @protected
   * @abstract
   */
  class EmbeddedConnectionManager extends ConnectionManager {
  
      /**
       * Creates a new EmbeddedConnectionManager
       * @param {ConnectionProfileManager} connectionProfileManager
       * - the ConnectionProfileManager used to manage access connection profiles.
       */
      constructor(connectionProfileManager) {
          super(connectionProfileManager);
          this.dataService = new EmbeddedDataService(null, true);
      }
  
      /**
       * Import an identity into a profile wallet or keystore.
       * @param {string} connectionProfile The name of the connection profile
       * @param {object} connectionOptions The connection options loaded from the profile
       * @param {string} id the id to associate with the identity
       * @param {string} certificate the certificate
       * @param {string} privateKey the private key
       */
      async importIdentity(connectionProfile, connectionOptions, id, certificate, privateKey) {
          const identities = await this.dataService.ensureCollection(IDENTITY_COLLECTION_ID);
          const certificateObj = new Certificate(certificate);
          const identifier = certificateObj.getIdentifier();
          const publicKey = certificateObj.getPublicKey();
          const name = certificateObj.getName();
          const issuer = certificateObj.getIssuer();
          let secret = uuid.v4().substring(0, 8);
          let options = {};
  
          // Allow an existing identity to be replaced in the connector wallet.
          if (await identities.exists(id)) {
              const curid = await identities.get(id);
              secret = curid.secret;
              options = curid.options;
              await identities.remove(id);
          }
          const identity = {
              identifier,
              name,
              issuer,
              secret,
              certificate,
              publicKey,
              privateKey,
              imported: true,
              options
          };
  
          await identities.add(id, identity);
      }
  
       /**
       * Obtain the credentials associated with a given identity.
       * @param {String} connectionProfileName - Name of the connection profile.
       * @param {Object} connectionOptions - connection options loaded from the profile.
       * @param {String} id - Name of the identity.
       * @return {Promise} Resolves to credentials in the form <em>{ certificate: String, privateKey: String }</em>, or
       * {@link null} if the named identity does not exist.
       */
      async exportIdentity(connectionProfileName, connectionOptions, id) {
          const identities = await this.dataService.ensureCollection(IDENTITY_COLLECTION_ID);
          const exists = await identities.exists(id);
          if (!exists) {
              return null;
          }
  
          const { certificate, privateKey, imported } = await identities.get(id);
          if (imported) {
              return { certificate, privateKey };
          }
          return null;
      }
  
      /**
       * Remove an identity from the profile wallet.
       * @param {string} connectionProfile The name of the connection profile
       * @param {object} connectionOptions The connection options loaded from the profile
       * @param {string} id the id to associate with the identity
       * @returns {Promise} a promise which resolves to true if identity existed and removed, false otherwise
       * or rejects with an error.
       */
      async removeIdentity(connectionProfile, connectionOptions, id) {
          const identities = await this.dataService.ensureCollection(IDENTITY_COLLECTION_ID);
          const exists = await identities.exists(id);
          if (!exists) {
              return exists;
          }
          const identity = await identities.get(id);
          if (identity.imported) {
              identity.imported = false;
              await identities.update(id, identity);
              return true;
          }
  
          return false;
      }
  
     /**
       * Establish a connection to the business network.
       * @param {string} connectionProfile The name of the connection profile
       * @param {string} businessNetworkIdentifier The identifier of the business network
       * @param {object} connectionOptions The connection options loaded from the profile
       * @return {Promise} A promise that is resolved with a {@link Connection}
       * object once the connection is established, or rejected with a connection error.
       */
      async connect(connectionProfile, businessNetworkIdentifier, connectionOptions) {
          return new EmbeddedConnection(this, connectionProfile, businessNetworkIdentifier);
      }
  
  }
  
  module.exports = EmbeddedConnectionManager;
  