 function _nullishCoalesce(lhs, rhsFn) { if (lhs != null) { return lhs; } else { return rhsFn(); } }import { buildReducer, memoizeReducer } from 'redux-keto'


import { verifyData } from '../../util/crypto/verify'
import { base58 } from '../../util/encoding'


import { searchTree } from './login'


import { findPin2Stash } from './pin2'












export const login = buildReducer({
  apiKey(state = '', action) {
    return action.type === 'INIT' ? action.payload.apiKey : state
  },

  apiSecret(state = null, action) {
    return action.type === 'INIT' ? _nullishCoalesce(action.payload.apiSecret, () => ( null)) : state
  },

  contextAppId(state = '', action) {
    return action.type === 'INIT' ? action.payload.appId : state
  },

  deviceDescription(state = null, action) {
    return action.type === 'INIT' ? action.payload.deviceDescription : state
  },

  localUsers: memoizeReducer(
    (next) => next.login.contextAppId,
    (next) => next.login.stashes,
    (next) => next.clientInfo,
    (appId, stashes, clientInfo) => {
      function processStash(stashTree) {
        const { lastLogin, loginId, recovery2Key, username } = stashTree

        const stash = searchTree(stashTree, stash => stash.appId === appId)
        const keyLoginEnabled =
          stash != null &&
          (stash.passwordAuthBox != null || stash.loginAuthBox != null)
        const pin2Stash = findPin2Stash(stashTree, appId)

        return {
          keyLoginEnabled,
          lastLogin,
          loginId: base58.stringify(loginId),
          pinLoginEnabled: pin2Stash != null,
          recovery2Key:
            recovery2Key != null ? base58.stringify(recovery2Key) : undefined,
          username,
          voucherId: stash != null ? stash.voucherId : undefined
        }
      }

      const duressStash =
        clientInfo.duressLoginId != null
          ? stashes.find(stash => stash.loginId === clientInfo.duressLoginId)
          : undefined
      if (duressStash != null) {
        return [processStash(duressStash)]
      } else {
        return stashes.map(processStash)
      }
    }
  ),

  loginServers(state = [], action) {
    return action.type === 'INIT' ? action.payload.loginServers : state
  },

  stashes(state = [], action) {
    switch (action.type) {
      case 'INIT': {
        return action.payload.stashes
      }

      case 'LOGIN_STASH_DELETED': {
        const loginId = action.payload
        return state.filter(
          stashTree => !verifyData(stashTree.loginId, loginId)
        )
      }

      case 'LOGIN_STASH_SAVED': {
        const newStashTree = action.payload
        const out = state.filter(
          stashTree => !verifyData(stashTree.loginId, newStashTree.loginId)
        )
        out.unshift(newStashTree)
        return out
      }
    }
    return state
  },

  walletInfos(state, action, next) {
    // Optimize the common case:
    if (next.accountIds.length === 1) {
      const id = next.accountIds[0]
      return next.accounts[id].walletInfos
    }

    const out = {}
    for (const accountId of next.accountIds) {
      const account = next.accounts[accountId]
      for (const id of Object.keys(account.walletInfos)) {
        const info = account.walletInfos[id]
        out[id] = info
      }
    }
    return out
  }
})
