
import { ENCRYPT_IV, ENCRYPT_KEY } from '../consts';
import { WhiteListModel } from '../db/RegionWhiteList';
const fs = require('fs');
const path = require('path');
import { aesDecrypt, aesEncrypt } from './util';
const crypto = require('crypto');
const isJSON = require('koa-is-json');

const privateKey = fs.readFileSync(path.resolve(__dirname, `../resource/privateKey`));
const publicKey = fs.readFileSync(path.resolve(__dirname, `../resource/publicKey`)); // 发推送加密的秘钥，和privateKey不是一对


export async function checkWhiteList(env: string, ip: string, uid: number) {
    if(ip) {
        let result = await WhiteListModel.checkIp(env, ip);
        if(!!result) return true;
    }
    if(uid) {
        let result = await WhiteListModel.checkUid(env, uid);
        if(!!result) return true;
    }
    return false
}

export class MsgEncrypt {
    private k: string = ENCRYPT_KEY;
    private v: string = ENCRYPT_IV;
    private encodeK: string = '';
    private encodeV: string = '';

    constructor(data: { k?: string, v?: string, encodeK?: string, encodeV?: string, originK?: string, originV?: string }) {
        if(data.k && data.v) {
            this.encodeAndSetKv(data.k, data.v);
        }
        if(data.encodeK && data.encodeV) {
            this.decodeAndSetKv(data.encodeK, data.encodeV);
        }
        if(data.originK && data.originV) {
            this.k = data.originK;
            this.v = data.originV;
        }
    }

    public decryptMsg(data: string) {
        if(!data) return false

        try {
            const decodeStr = aesDecrypt(data, this.k, this.v);
            console.log('decoded str:', decodeStr);

            let body = JSON.parse(decodeStr);
            return body
        } catch(e) {
            console.error(e);
            return false;
        }
    }

    public encryptMsg(json: Object) {
        if(!isJSON(json)) return false;

        try {
            const encodeStr = aesEncrypt(JSON.stringify(json), this.k, this.v);
            // console.log('encode str:', encodeStr);

            return encodeStr;
        } catch(e) {
            console.error(e);
            return false;
        }
    }

    public decodeAndSetKv(requestK: string, requestV: string) {
        if(requestK) {
            this.encodeK = requestK;
            this.k = this.privateDecrypt(Buffer.from(requestK, 'base64'));
        }
        if(requestV) {
            this.encodeV = requestV;
            this.v = this.privateDecrypt(Buffer.from(requestV, 'base64'));
        }
        return this.getKv();
    }

    public getKv() {
        return { aesKey: this.k, aesIV: this.v }
    }

    public getEncodeKv() {
        return { aesKey: this.encodeK, aesIV: this.encodeV }
    }

    private privateDecrypt(encryptMsg: Buffer) {
        const decryptMsg = crypto.privateDecrypt(
          { key: privateKey, padding: crypto.constants.RSA_PKCS1_PADDING },
          encryptMsg
        );
        return decryptMsg.toString();
    }
    
    private getRsaEncodedData(original: string) {
        const encryptMsg = crypto.publicEncrypt(
            { key: publicKey, padding: crypto.constants.RSA_PKCS1_PADDING },
            Buffer.from(original)
          );
        return encryptMsg.toString('base64');
    }

    private encodeAndSetKv(k: string, v: string) {
        if(k) {
            this.k = k;
            this.encodeK = this.getRsaEncodedData(k);
        }
        if(v) {
            this.v = v;
            this.encodeV = this.getRsaEncodedData(v);
        }
    }
}

