#include "nodes/base/base.hpp"
#include "nodes/stream/streamNode.hpp"
#include "nodes/infer/inferNode.hpp"
#include "nodes/draw/drawNode.hpp"
#include "nodes/httpPush/httpPush.hpp"


void test_depth()
{
    std::shared_ptr<Node::StreamNode> src_node0   = std::make_shared<Node::StreamNode>("src0", "rtsp://admin:lww123456@172.16.22.16:554/Streaming/Channels/201", 0, Node::DecodeType::GPU);
    src_node0->set_skip_frame(10);

    std::shared_ptr<Infer> depth_model = load("model/depth.engine", ModelType::DEPTH_ANYTHING, {}, 0, 0.25, 0.45);
    std::shared_ptr<Node::InferNode> infer_node   = std::make_shared<Node::InferNode>("depth");
    infer_node->set_model_instance(depth_model, ModelType::DEPTH_ANYTHING);

    std::shared_ptr<Node::DrawNode> draw_node     = std::make_shared<Node::DrawNode>("draw");
    std::shared_ptr<Node::HttpPushNode> push_node = std::make_shared<Node::HttpPushNode>("push", "172.16.20.168", 8080, "/push");
    
    Node::LinkNode(src_node0, infer_node);
    Node::LinkNode(infer_node, draw_node);
    Node::LinkNode(draw_node, push_node);
    push_node->start();
    draw_node->start();
    infer_node->start();
    src_node0->start();
    getchar();
}

void test_yolo()
{
    std::vector<std::string> names = { "person", "clothes", "vest" };
    std::shared_ptr<Node::StreamNode> src_node0   = std::make_shared<Node::StreamNode>("src0", "rtsp://admin:lww123456@172.16.22.16:554/Streaming/Channels/201", 0, Node::DecodeType::GPU);
    src_node0->set_skip_frame(10);

    std::shared_ptr<Infer> yolo_model = load("model/yolo11s.engine", ModelType::YOLO11, names, 0, 0.25, 0.45);
    std::shared_ptr<Node::InferNode> infer_node   = std::make_shared<Node::InferNode>("yolo11");
    infer_node->set_model_instance(yolo_model, ModelType::YOLO11);

    std::shared_ptr<Node::DrawNode> draw_node     = std::make_shared<Node::DrawNode>("draw");
    std::shared_ptr<Node::HttpPushNode> push_node = std::make_shared<Node::HttpPushNode>("push", "172.16.20.168", 8080, "/push");
    
    Node::LinkNode(src_node0, infer_node);
    Node::LinkNode(infer_node, draw_node);
    Node::LinkNode(draw_node, push_node);
    push_node->start();
    draw_node->start();
    infer_node->start();
    src_node0->start();
    getchar();
}

void test_multi()
{
    std::vector<std::string> names = { "person", "clothes", "vest" };

    std::shared_ptr<Node::StreamNode> src_node0   = std::make_shared<Node::StreamNode>("src0", "rtsp://admin:lww123456@172.16.22.16:554/Streaming/Channels/101", 0, Node::DecodeType::GPU);
    src_node0->set_skip_frame(10);

    std::shared_ptr<Node::StreamNode> src_node1   = std::make_shared<Node::StreamNode>("src1", "rtsp://admin:lww123456@172.16.22.16:554/Streaming/Channels/201", 0, Node::DecodeType::GPU);
    src_node1->set_skip_frame(10);

    std::shared_ptr<Node::StreamNode> src_node2   = std::make_shared<Node::StreamNode>("src2", "rtsp://admin:lww123456@172.16.22.16:554/Streaming/Channels/301", 0, Node::DecodeType::GPU);
    src_node2->set_skip_frame(10);

    std::shared_ptr<Infer> yolo_model = load("model/yolo11s.engine", ModelType::YOLO11, names, 0, 0.25, 0.45);
    std::shared_ptr<Node::InferNode> infer_node1   = std::make_shared<Node::InferNode>("yolo11");
    infer_node1->set_model_instance(yolo_model, ModelType::YOLO11);

    std::shared_ptr<Infer> depth_model = load("model/depth.engine", ModelType::DEPTH_ANYTHING, {}, 0, 0.25, 0.45);
    std::shared_ptr<Node::InferNode> infer_node2   = std::make_shared<Node::InferNode>("depth");
    infer_node2->set_model_instance(depth_model, ModelType::DEPTH_ANYTHING);

    std::shared_ptr<Node::DrawNode> draw_node     = std::make_shared<Node::DrawNode>("draw");
    std::shared_ptr<Node::HttpPushNode> push_node = std::make_shared<Node::HttpPushNode>("push", "172.16.20.168", 8080, "/push");

    Node::LinkNode(src_node0, infer_node1);
    Node::LinkNode(src_node1, infer_node1);
    Node::LinkNode(src_node2, infer_node1);
    Node::LinkNode(infer_node1, infer_node2);
    Node::LinkNode(infer_node2, draw_node);
    Node::LinkNode(draw_node, push_node);
    push_node->start();
    draw_node->start();
    infer_node1->start();
    infer_node2->start();
    src_node0->start();
    src_node1->start();
    src_node2->start();
    getchar();
}

int main()
{
    test_multi();
    
    return 0;
}


// TODO
// 硬解码、软解码    完成 软解使用opencv + ffmpeg，硬解使用nvcodec + ffmpeg
// 模型复用         完成，基类加锁保证一致性
// 画图节点         完成
// 推送节点         基本完成

// 分析节点         
// depth-anything    进行中
// YOLO11 seg 
// 通过配置文件创建 pipeline
// 日志
// 设置电子围栏


python3 detect.py --weights carperson/carperson.pt --source carperson/carperson.mp4