var idtimerAutoFactory = null;
var continueFlag = true; //
var fd;
var fdCw;
var outTime = 0; //自动推出计数器
var touchFlag = 0;
var uart = require("factory_uartUtil.js");
var _userdata = require("userdata.js");
var userData = _userdata.userData;
var autoUtil = require("factory_autoFactoryTestUtil.js");
var autoFactoryState = false;

var uartMode = 2 //0:uart 1:uart_carrie_wave
/* ================= 1. 路由表：关键字 → 处理函数 ================= */
const cmdTable = [
    { kw: 'TEST_START', fn: doStart },
    { kw: 'VERSION', fn: doVersion },
    { kw: 'DUT_START', fn: doDutStart },
    { kw: 'SCAN', fn: doScan },
    { kw: 'OTG_TEST', fn: doOtg },
    { kw: 'LCD', fn: doLcd },
    { kw: 'TOUCHKEY', fn: doKeyBz },
    { kw: 'TEMPATURE', fn: doTempHum },
    { kw: 'WRITE_MAC', fn: doWriteMac },
    { kw: 'GET_MAC', fn: doGetMac },
    { kw: 'WRITE_SN', fn: doWriteSn },
    { kw: 'GET_SN', fn: doGetSn },
    // { kw: 'WRITE_LIC', fn: doWriteLic },
    { kw: 'GET_CRC', fn: doGetCrc },
    { kw: 'TEST_END', fn: doEnd },
    { kw: 'RTC', fn: doGetRtc },
];
const cmdTableHex = [
    { kw: '57524954455F4C4943', fn: doWriteLic }, //WRITE_LIC
];

/* ================= 2. 统一入口：模糊匹配================= */
function event(fd, recvBuf) {
    console.log('RX:' + recvBuf);
    const hit = cmdTable.find(item => recvBuf.includes(item.kw));
    if (hit) return hit.fn(fd, recvBuf);
}
function eventHex(fd, recvBuf) {
    console.debug(`RXHEX:${recvBuf}`);
    //console.debug(`!!!!will go to main globalThis.appAliveValue!=1 ${globalThis.appAliveValue}`)
    const hit = cmdTableHex.find(item => recvBuf.includes(item.kw));
    if (hit) return hit.fn(fd, recvBuf);
}

/* ================= 3. 处理函数 ================= */

function doStart(fd) {
    setCountdownStatus(false); //关闭倒计时直到接到通知关闭
    send(fd, '+START');
    autoUtil.initUI();
    // autoUtil.setAutoModeUI("INIT");
}


function doGetRtc(fd) {
    var time = "+" + autoUtil.getRtcTimer()
    console.log('RTC:' + time);
    send(fd, time);
}

function doVersion(fd) {
    var version = "+" + userData.softwareVersion
    // var version = "+" + "V0.0.112"
    console.log("version: " + version);
    send(fd, version);
}
function doDutStart(fd, recvBuf) {
    console.log("doDutStart");
    if (doDutStart._scanTimerOut === undefined) {
        doDutStart._scanTimerOut = null;
    }
    if (doDutStart._scanTimerOut != null) {
        clearTimeout(doDutStart._scanTimerOut);
        doDutStart._scanTimerOut = null;
    }
    autoUtil.startWifiScan();
    autoUtil.setSsid(recvBuf);
    doDutStart._scanTimerOut = setTimeout(function () {
        send(fd, '+OK');
    }, 5000);
}

function doScan(fd, recvBuf) {
    var chekssid = autoUtil.getssid()
    var value = autoUtil.getWifiScan(chekssid);   // if (value != "null") {
    var scanList = "+" + value;
    send(fd, scanList);
}
function doOtg(fd) {
    if (autoUtil.checkUsbDeviceExist() == true) {
        console.log("doOtg 1")
        send(fd, '+OK');
    } else {
        console.log("doOtg 0")
        send(fd, '+FAIL');
    }
}

function doLcd(fd) {
    if (doLcd.cntLcd == undefined) {
        doLcd.cntLcd = 0;
    }
    doLcd.cntLcd += 1;
    console.log("doLcd " + doLcd.cntLcd)
    if (doLcd.cntLcd > 1) {
        autoUtil.ledTimerOut();
        send(fd, '+OK');
        doLcd.cntLcd = 0;
    } else {
        // autoUtil.setAutoModeUI("INIT");
        autoUtil.initUI();
        autoUtil.setAutoModeUI("LCD");
    }

}


function doTempHum(fd) {
    var tempHum = "+" + autoUtil.getTempHum();
    console.log("tempHum: " + tempHum);
    send(fd, tempHum);
}
function doGetMac(fd) {
    var wifimac = autoUtil.getWifiInfo("address");
    var licmac = autoUtil.getMacAddressFromLicenseFile();
    console.log("wifimac: " + wifimac + " licmac: " + licmac);
    var mac = "+" + wifimac
    if (wifimac === licmac) {
        send(fd, mac);
    } else
        send(fd, "+FAIL");
}
function doGetSn(fd) {
    var sn = "+" + autoUtil.getSn();
    console.log('get sn: ' + sn);
    send(fd, sn);
}
function doGetCrc(fd) {
    // var crc = "+" + autoUtil.getCrc();
    var crc = autoUtil.testLicParce();
    if (crc != "null") {

        var crcVal = "+" + crc
        console.log('crcVal: ' + crcVal);
        send(fd, crcVal);
    }
}
function doEnd(fd) {
    send(fd, '+OK');

    autoUtil.exitAutoFactoryPage();
    exitAutoFactory();
}

function doWriteMac(fd, recvBuf) {
    // const mac = recvBuf.split('=')[1].trim();
    console.log('write mac:' + mac);
    send(fd, '+OK');
}
function doWriteSn(fd, recvBuf) {
    const sn = recvBuf.split('=')[1].trim();
    console.log('write sn:' + sn);
    autoUtil.writeSn(sn);

    send(fd, '+OK');
}
function doWriteLic(fd, recvBuf) {
    console.log("recvBuf:" + recvBuf)
    var ret = autoUtil.licParce(recvBuf);
    if (ret == 1) {
        console.log("licParce ret:" + ret)
        send(fd, '+OK');
    }
    else if (ret == 2) {
        console.log("licParce error");
        if (uartMode == 1) {
            restartUart();
        } else if (uartMode == 2) {
            restartUartCarrieWave();
        }
    }
    else if (ret == 3) {
        console.log("licParce ret:" + ret)
        send(fd, '+OK');
        autoUtil.gotoWriteLic();
    }
    // console.log('!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!');
    // console.log('write lic:' + recvBuf);
    // var hex = autoUtil.formatHexWithSpace(recvBuf)
    // console.log('hex:' + hex);

    // send(fd, '+OK');
}
function doKeyBz(fd, recvBuf) {
    /* 人工弹窗可接 UI，这里直接返回 OK */
    // autoUtil.setAutoModeUI("INIT");
    autoUtil.initUI();
    autoUtil.setAutoModeUI("TOUCH");
    touchFlag = 1;
    // send(fd, '+OK');
}
// 想加 TOUCH4、5…直接往后写
// 3 键就是 0b111
let collectMask = 0;
function manualKeyBz(buf) {
    const KEYS = ['TOUCH1', 'TOUCH2', 'TOUCH3'];
    const TARGET_MASK = (1 << KEYS.length) - 1;         // 0b111
    const idx = KEYS.indexOf(buf);
    if (idx === -1) return;

    collectMask |= 1 << idx;
    if (collectMask === TARGET_MASK) {
        collectMask = 0;
        if (touchFlag == 1) {
            send(getFd(), '+OK');
            touchFlag = 0;
        }
    }
}



function initEvent(fd) {
    autoUtil.startWifiScan();

    setCountdownStatus(true);
}

function exitAutoFactory() {
    if (idtimerAutoFactory != null) {
        clearInterval(idtimerAutoFactory);
        idtimerAutoFactory = null;
    }
    setCountdownStatus(true);
    close(fd);
}

function uart() {
    if (idtimerAutoFactory != null) {
        clearInterval(idtimerAutoFactory);
        idtimerAutoFactory = null;
    }
    fd = init();

    if (fd < 0) {
        console.log("!!!uart_init error");
        return;
    }
    initEvent();
    console.log("uart_init ok");
    idtimerAutoFactory = setInterval(function () {

        uartFd(fd);
        // testUartFd(fd);

        console.log("!!!auto ing :" + outTime);
        //cnt30s(fd);
    }, 1000)

}
function uartCarrieWave() {
    if (idtimerAutoFactory != null) {
        clearInterval(idtimerAutoFactory);
        idtimerAutoFactory = null;
    }
    const baud_str = "4800";
    const port = pickUartDev();
    if (!port) return -1;
    var setTimerOutStartUart = kill_tty(port);

    setTimeout(() => {

        // fd = init();
        fd = initCarrieWave(port, baud_str)
        if (fd < 0) {
            console.log("!!!uart_init error");
            return;
        }
        uart_set_mode(fd, "raw")
        initEvent(fd);
        console.log("uart_init ok");
        idtimerAutoFactory = setInterval(function () {

            uartFd(fd);
            // testUartFd(fd);


            console.log("!!!auto ing :" + outTime);
            cnt30s(fd);
        }, 1000)
    }, setTimerOutStartUart);
}

function autoFactoryTestTimer() {
    if (uartMode == 1) {
        uart();
    }
    else if (uartMode == 2) {
        uartCarrieWave();
    }
}


function testUartFd(fd) {
    var recvBuf = recv(fd);
    console.log("recv:" + recvBuf);
    // event(fd, recvBuf)
    var recvHexBuf = recvHex(fd)
    console.log("recvHex:" + recvHexBuf);
    send(fd, '+TESTSEND');
}

function uartFd(fd) {
    var recvBuf = recv(fd);
    console.log("recv:" + recvBuf);
    event(fd, recvBuf)
    var recvHexBuf = recvHex(fd)
    // console.log("recvHex:" + recvHexBuf);
    eventHex(fd, recvHexBuf)
}

function cnt30s(fd) {
    if (outTime > 60) {
        console.log("!!!outTime > 60");
        exitAutoFactory();
        return;
    }
    if (getCountdownStatus() == true)
        ++outTime;
}

function setCountdownStatus(sta) {
    continueFlag = sta;
}


function getCountdownStatus() {
    return continueFlag
}

function send(fd, cmd) {
    var cmdBuf = cmd + "\r\n";
    var len = cmdBuf.length;   // 返回 8
    console.log("!!TX:" + cmdBuf + "(len):" + cmdBuf.length);
    return uart.uart_send(fd, cmdBuf, len);
}


function recv(fd) {
    return uart.uart_recv(fd) || "";
}
function recvHex(fd) {
    return uart.uart_recv_hex(fd) || "";
}

function recvBin(fd) {
    return uart.uart_recv_bin(fd) || "";
}
function init() {
    var port = "/dev/ttyS4";
    var baud_str = "115200";
    return uart.uart_init(port, baud_str);

}
function getUartConfig() {
    return {
        ln_sPort: "/dev/ttyProto",
        old_port: "/dev/ttyS0",
        baud_str: "115200"
    }
}
// 统一找串口设备，返回选中的设备路径；失败返回 null
function pickUartDev() {
    const { ln_sPort, old_port } = getUartConfig();
    if (autoUtil.devExist(ln_sPort)) return ln_sPort;
    console.log(`!!!${ln_sPort} not exist`);
    if (autoUtil.devExist(old_port)) return old_port;
    console.log(`!!!${old_port} not exist`);
    return null;
}

function kill_tty(port) {
    var setTimerOutStartUart = 0;               // 无可用设备
    var killed = uart.kill_tty_user(port);
    if (killed > 0) {
        console.log("Killed " + killed + " process(es) using " + port + ", waiting 200 ms...");
        setTimerOutStartUart = 300
    } else {
        setTimerOutStartUart = 30
    }
    return setTimerOutStartUart

}
function initCarrieWave(port, baud_str) {
    console.log("!!initCarrieWave");
    setAutoFactory(true)
    uart.pwm_uart_init()
    return uart.uart_init(port, baud_str);


}


function close(fd) {
    if (fd >= 0) {
        uart.uart_close(fd);
        fd = -1;
    }
    setAutoFactory(false)

}

function setFd(fdvar) {
    fd = fdvar;
}
function getFd() {
    return fd;
}

/* ========== 新增：重启串口 ========== */
function restartUart() {
    console.log("!!=== restart Uart restart Uart restart Uart===");
    /* 1. 如果之前已打开，先关闭 */
    if (fd >= 0) {
        uart.uart_close(fd);
        fd = -1;
    }
    /* 2. 重新初始化 */
    fd = init();               // 沿用原 init() 配置
    if (fd < 0) {
        console.log("reset usart error");
        return -1;
    }
    console.log("reset usart success,fd=" + fd);
    return fd;
}
/* ========== 新增：重启串口 ========== */
function restartUartCarrieWave() {
    console.log("!!=== restart Uart restart Uart restart Uart===");
    /* 1. 如果之前已打开，先关闭 */
    if (fd >= 0) {
        uart.uart_close(fd);
        fd = -1;
    }
    /* 2. 重新初始化 */
    const baud_str = "4800";
    const port = pickUartDev();
    if (!port) {
        console.log("!!!get pickUartDev error");
        return -1;
    }
    fd = initCarrieWave(port, baud_str)

    if (fd < 0) {
        console.log("reset usart error");
        return -1;
    }
    uart_set_mode(fd, "raw")
    console.log("reset usart success,fd=" + fd);
    return fd;
}

function uart_set_mode(fd, mode) {
    switch (mode) {
        case "canonical": uart.uart_set_canonical(fd); break;
        case "raw": uart.uart_set_raw(fd); break;
        default: uart.uart_set_canonical(fd);
    }

}

function setAutoFactory(state) {
    autoFactoryState = state;
}
function getAutoFactory(state) {
    return autoFactoryState
}


function exclear2Xuart() {
    console.log("!!!_exclear2Xuart");
    // exitAutoFactory();
    // const port = pickUartDev();
    // if (!port) return -1;
    // return  kill_tty(port);
    return 1;
    // setTimeout(() => {
    // }, 1000);

}

module.exports = {
    autoFactoryTestTimer: autoFactoryTestTimer,
    getAutoFactory: getAutoFactory,
    exclear2Xuart: exclear2Xuart,
    manualKeyBz: manualKeyBz,
    restartUart: restartUart
}
