//
// Created by zx on 2019/12/28.
//
#include <iostream>
#include "plc_communicator.h"

class Test{
public:
    Test(Plc_Communicator* p){
        mp_pc = p;
    }
    static Error_manager callback(int terminal_id, void *p_owner)
    {
        Test* t = (Test*)p_owner;
        t->m_term_id = terminal_id;
        std::cout<<"callback "<<t->m_term_id<<" called."<<std::endl;
        usleep(1000 * 1000);
        if(t->mp_pc!=0){
            // Plc_Task task;
            struct measure_result result;
            result.terminal_id = t->m_term_id;
            result.correctness = terminal_id % 2 == 0?true:false;
            result.x = 3501.2f;
            result.angle = 91.35f;
            result.wheel_base = 2651.6f;
            Error_manager ec = t->m_task.set_result(result);
            std::cout<<"callback set result "<<ec.to_string()<<std::endl;
            std::thread* th = new std::thread(execute_thread, t);
            th->detach();
        }
        return Error_manager(Error_code::SUCCESS);
    }

    static void execute_thread(Test* t){
        usleep(1000 * 2000);
        if(t->mp_pc!= 0){
            Error_manager ec = t->mp_pc->execute_task(&t->m_task);
            std::cout << "thread execute task " << ec.to_string() << std::endl;

            int count = 1;
            while (count-- > 0)
            {
                std::cout << "---------- "<<count<<" --------" << std::endl;
                std::vector<uint16_t> vec;
                ec = t->mp_pc->get_plc_data(vec, t->m_term_id);
                std::cout << "get data " << ec.to_string() << std::endl;
                std::cout << "[ ";
                for (size_t i = 0; i < vec.size(); i++)
                {
                    std::cout << vec[i] << " ";
                }
                std::cout << "]" << std::endl;

                ec = t->mp_pc->set_status_update_timeout(15000);
                std::cout << "set status " << ec.to_string() << std::endl;

                ec = t->mp_pc->get_error();
                std::cout << "get error " << ec.to_string() << std::endl;

                bool init_state = t->mp_pc->get_initialize_status();
                std::cout << "get initialize status " << init_state << std::endl;

                bool conn = t->mp_pc->get_connection();
                std::cout << "get connection status " << conn << std::endl;
                usleep(1000 * 1500);
            }
        }
    }
private:
    int m_term_id;
    Plc_Communicator* mp_pc;
    Plc_Task    m_task;
};

int main(int argc,char* argv[])
{
    google::InitGoogleLogging("plc");
    plc_module::plc_connection_params params;
    params.set_ip("192.168.2.131");
    params.set_port(502);
    params.set_slave_id(1);
    Plc_Communicator pc(params);
    Test test(&pc);
    Error_manager ec = pc.set_plc_callback(test.callback, &test);
    std::cout<<"set callback "<<ec.to_string()<<std::endl;

    // Error_manager ec = Error_manager(Error_code::SUCCESS);
    // // Error_manager ec = Error_manager(Error_code::SUCCESS, Error_level::NEGLIGIBLE_ERROR, "测试。。。");
    // std::cout<<"test 000"<<std::endl;
    // std::cout<<"test "<<ec.get_error_code()<<std::endl;
    // std::cout<<"test "<<ec.get_error_level()<<std::endl;
    // std::cout<<"test "<<ec.get_error_description()<<std::endl;
    // std::cout<<"test "<<ec.to_string()<<std::endl;

    getchar();
    google::ShutdownGoogleLogging();
    return 0;
}