const path = require('path');
const get = require('lodash/get');
const joinUrl = require('url-join');
const DiskStorage = require('@arcblock/did-auth-storage-nedb');
const { WalletAuthenticator, WalletHandlers } = require('@arcblock/did-auth');

const { getBlockletLogo } = require('../util');

module.exports = (node, opts) => {
  const authenticator = new WalletAuthenticator({
    wallet: async ({ request }) => {
      const { wallet } = await request.getBlockletInfo();
      return wallet.toJSON();
    },

    appInfo: async ({ request, baseUrl }) => {
      const groupPathPrefix = request.headers['x-group-path-prefix'] || '/';

      const [blocklet, meta, info] = await Promise.all([
        request.getBlocklet(),
        request.getBlockletInfo(),
        request.getNodeInfo(),
      ]);

      // logo
      const logo = getBlockletLogo({ baseUrl: joinUrl(baseUrl, opts.prefix), blocklet, nodeInfo: info });

      return {
        name: meta.name,
        description: meta.description || `Login to ${meta.name}`,
        icon: logo,
        link: blocklet.interfaces[0].url,
        updateSubEndpoint: true,
        subscriptionEndpoint: joinUrl(groupPathPrefix, opts.prefix, 'websocket'),
        nodeDid: info.did,
      };
    },

    chainInfo: async ({ request }) => {
      const blocklet = await request.getBlocklet();
      // userEnvironments.CHAIN_HOST is for backward compatible
      const chainHost = get(blocklet, 'configObj.CHAIN_HOST') || get(blocklet, 'userEnvironments.CHAIN_HOST');
      return chainHost ? { host: chainHost, id: 'chain' } : { host: 'none', id: 'none' };
    },
  });

  const handlers = new WalletHandlers({
    authenticator,
    options: {
      prefix: `${opts.prefix}/api/did`,
    },
    tokenGenerator: () => Date.now().toString(),
    tokenStorage: new DiskStorage({
      dbPath: path.join(opts.dataDir, 'auth.db'),
      dbPort: process.env.NODE_ENV === 'test' ? null : Number(process.env.NEDB_MULTI_PORT),
    }),
  });

  return {
    authenticator,
    handlers,
  };
};
