/*
 * Copyright 2024 KylinSoft Co., Ltd.
 *
 * This program is free software: you can redistribute it and/or modify it under
 * the terms of the GNU General Public License as published by the Free Software
 * Foundation, either version 3 of the License, or (at your option) any later
 * version.
 *
 * This program is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
 * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
 * details.
 *
 * You should have received a copy of the GNU General Public License along with
 * this program. If not, see <https://www.gnu.org/licenses/>.
 */

// c
#include <cstdio>

// cpp
#include <filesystem>
#include <fstream>
#include <thread>
#include <vector>

// glib
#include <gio/gio.h>

// kysdk-ai coreai speech

#include "coreai/speech/audioconfig.h"
#include "coreai/speech/audiodatastream.h"
#include "coreai/speech/error.h"
#include "coreai/speech/recognizer.h"
#include "coreai/speech/result.h"

// test
#include "ModelConfig.h"

// util
#include "logger.h"

// 开始：测试通过麦克风语音识别
class ModelChangeTool {
public:
    ModelChangeTool() {
        stdinChannel = g_io_channel_unix_new(STDIN_FILENO);
        g_io_channel_set_encoding(stdinChannel, nullptr, nullptr);
        g_io_channel_set_buffered(stdinChannel, TRUE);
        g_io_channel_set_flags(stdinChannel, G_IO_FLAG_NONBLOCK, nullptr);
        g_io_add_watch(stdinChannel,
                       GIOCondition(G_IO_IN | G_IO_HUP | G_IO_ERR),
                       onStdinEnter, this);

        mainLoop = g_main_loop_new(nullptr, false);
    }

    ~ModelChangeTool() {
        g_main_loop_unref(mainLoop);
        g_io_channel_unref(stdinChannel);
    }

    void run() { g_main_loop_run(mainLoop); }

private:
    static gboolean onStdinEnter(GIOChannel *channel, GIOCondition condition,
                                 gpointer userData) {
        ModelChangeTool *tool = (ModelChangeTool *)userData;
        gchar *line{nullptr};
        if (condition & G_IO_IN) {
            GIOStatus status = g_io_channel_read_line(channel, &line, nullptr,
                                                      nullptr, nullptr);
            if (status == G_IO_STATUS_NORMAL) {
                std::string input(line);
                if (!input.empty() && input[input.size() - 1] == '\n') {
                    input.erase(input.size() - 1);
                }
                control(input, tool);
                g_free(line);
            }
        }
        return TRUE;
    }

    static void control(const std::string &input, ModelChangeTool *tool) {
        if (input == "quit") {
            g_main_loop_quit(tool->mainLoop);
        } else if (input == "baidu") {
            LOGI("set current model baidu");
            setCurrentModel(ModelName::BAIDU);
        } else if (input == "xunfei") {
            LOGI("set current model xunfei");
            setCurrentModel(ModelName::XUNFEI);
        } else if (input == "current") {
            LOGI("current model:", getCurrentModelName());
        } else {
            LOGI();
        }
    }

private:
    GMainLoop *mainLoop{nullptr};
    GIOChannel *stdinChannel{nullptr};
};

int main() {
    try {
        setAllAuthentications();
        ModelChangeTool tool;
        tool.run();
    } catch (std::exception &exception) {
        LOGE("测试异常：", exception.what());
        return -1;
    }
    return 0;
}
