const assert = require('assert')
const fs = require('fs')
const path = require('path')
const vm = require('vm')

function loadModule(filePath, stubs = {}) {
  const source = fs.readFileSync(filePath, 'utf8')
  const exportedNames = []
  const transformed = source
    .replace(/^import .*$/gm, '')
    .replace(/export function\s+([A-Za-z0-9_]+)\s*\(/g, (_, name) => {
      exportedNames.push(name)
      return `function ${name}(`
    })
    .replace(/export default\s+/g, 'module.exports = ')

  const sandbox = {
    module: { exports: {} },
    exports: {},
    require,
    console,
    process: {
      env: {
        VUE_APP_PASSWORD_TRANSFER_KEY: '1234567890abcdef'
      }
    },
    ...stubs
  }

  vm.runInNewContext(
    `${transformed}\nmodule.exports = { ${exportedNames.join(', ')} };`,
    sandbox,
    { filename: filePath }
  )

  return sandbox.module.exports
}

const passwordTransferModule = loadModule(
  path.resolve(__dirname, '../src/utils/passwordTransfer.js'),
  { CryptoJS: require('crypto-js') }
)

const { encryptPasswordFields } = passwordTransferModule

const encrypted = encryptPasswordFields(
  { password: 'admin123', code: '8888' },
  ['password'],
  '1234567890abcdef'
)

assert.notStrictEqual(encrypted.password, 'admin123')
assert.strictEqual(encrypted.code, '8888')

const request = config => config
const loginModule = loadModule(
  path.resolve(__dirname, '../src/api/login.js'),
  { request, encryptPasswordFields }
)

const loginConfig = loginModule.login('admin', 'admin123', '8888', 'uuid-1')
assert.notStrictEqual(loginConfig.data.password, 'admin123')
assert.strictEqual(loginConfig.data.username, 'admin')

const registerConfig = loginModule.register({ username: 'u1', password: 'p1', confirmPassword: 'p1', code: '8888' })
assert.notStrictEqual(registerConfig.data.password, 'p1')
assert.strictEqual(registerConfig.data.confirmPassword, 'p1')

const userModule = loadModule(
  path.resolve(__dirname, '../src/api/system/user.js'),
  {
    request,
    encryptPasswordFields,
    parseStrEmpty: value => value
  }
)

const updatePwdConfig = userModule.updateUserPwd('oldPwd', 'newPwd')
assert.notStrictEqual(updatePwdConfig.data.oldPassword, 'oldPwd')
assert.notStrictEqual(updatePwdConfig.data.newPassword, 'newPwd')

const addUserConfig = userModule.addUser({ userName: 'u1', password: 'initPwd', nickName: 'n1' })
assert.notStrictEqual(addUserConfig.data.password, 'initPwd')

const resetUserPwdConfig = userModule.resetUserPwd(2, 'resetPwd')
assert.notStrictEqual(resetUserPwdConfig.data.password, 'resetPwd')

console.log('password-transfer-api test passed')
