const CryptoJS = require('./CryptoJs')
const hmacSHA256 = require('crypto-js/hmac-sha256')
const Hex = require('crypto-js/enc-hex')

/**
 * 特殊加密方式, 翻转、加盐、base64, hmacSHA256、Hex
 * 设置本地cookie，全部使用 httpOnly 本地js读取不了
 * @param {[string]} str 要加密的字符串
 * @param {[object]} res 请求响应对象
 * @param {[string]} name 设置cookie的名字
 * @param {[string]} domain 设置cookie的domain
 */
const setCookieByYiiWay = (str, res, name, domain) => {
  let expires = new Date(Date.now() + 30 * 24 * 60 * 60 * 1000)
  // 翻转、加盐、base64
  const salt = '0ZSGxuBkSJS5'
  let sup = str.split('').reverse().join('')
  let rad = Math.random()
  let token = salt + sup + rad
  sup = Buffer.from(token).toString('base64')
  let serialize = `a:2:{i:0;s:4:"_SUP";i:1;s:${sup.length}:"${sup}";}`
  let hamc = Hex.stringify(hmacSHA256(serialize, 'VzpR5JMDNqUsOZ0IFQARNLU9_0KLr9UC'))
  sup = hamc + serialize
  // 设置到cookie
  let opts = { path: '/', domain: domain, expires: expires, httpOnly: true }
  res.cookie(name, sup, opts)
}

/**
 * 统一设置 cookie，采用对称加密算法，将数据放入cookie中
 * @param {[string]} base64 base64字符串，必须传 base64转义过的 字符串
 * @param {[object]} res 请求响应对象
 * @param {[string]} name 设置cookie的名字
 * @param {[string]} domain 设置cookie的domain
 */
const setCookieData = (base64, res, name, domain) => {
  if (!base64) return
  let expires = new Date(Date.now() + 30 * 24 * 60 * 60 * 1000)
  let pwd = Buffer.from(base64, 'base64').toString()
  pwd = CryptoJS.encryptData(pwd)
  // 设置到cookie
  let opts = { path: '/', domain: domain, expires: expires, httpOnly: true }
  res.cookie(name, pwd, opts)
}

/**
 * 从cookie中，获取_SUP并解析成ticket
 * @param {[string]} _SUP cookie设置的值
 */
const getTicket = (_SUP) => {
  /* 服务端 解析ticket */
  let s = decodeURIComponent(_SUP || '') // tools.cookies.getCookie('_SUP') ||
  let ticket = ''
  s = s.match(/"([\d\w=]+)";\}$/)
  if (s && s.length === 2) {
    s = Buffer.from(s[1], 'base64').toString()
    s = s.slice(12, s.search('-TGT') + 4)
    ticket = s.split('').reverse().join('')
  }
  return ticket
}

module.exports = {
  getTicket: getTicket,
  setCookieByYiiWay: setCookieByYiiWay,
  setCookieData: setCookieData
}
