#include "globalfunc.h"
#include "gutil/qgui.h"
#include "basewin.h"
#define HAVE_REMOTE
#include "pcap.h"
#include <QMessageBox>
#include <QPushButton>

pcap_t *pcapSend{0};
PcapReThread *reThd{0};

QByteArray getNetDev(QWidget *parent, QByteArray def, bool justReturnIfHave) {
    char errbuf[PCAP_ERRBUF_SIZE];
    pcap_if_t *devs;
    if(pcap_findalldevs(&devs, errbuf) == -1) {
        QMessageBox::critical(parent, "Error", QString("寻找网卡失败")+errbuf);
        return QByteArray();
    }
    auto table = new Table{
            {"name", "网卡名称", 400},
            {"desc", "网卡描述", 300},
            {"loopback","Loopback"},
            {"ip","IP"},
            {"netmask","Netmask"},
            {"broadaddr","Broad Addr"},
            {"dstaddr","Dst Addr"}
    };

    pcap_if_t *device = 0;
    for(pcap_if_t *dev = devs; dev; dev = dev->next) {
        pcap_addr_t *a;
        for(a=dev->addresses; a; a=a->next) {
            auto sa_family = a->addr->sa_family;
            if(sa_family==AF_INET) {
                if(justReturnIfHave && ! def.isEmpty() && dev->name == def) {
                    pcap_freealldevs(devs);
                    table->deleteLater();
                    return def;
                }
                auto rr = table->rowCount();
                table->setRowCount(rr+1);
                table->setText(rr, "name", dev->name);
                table->setText(rr, "desc", dev->description);
                table->setText(rr, "loopback", (dev->flags & PCAP_IF_LOOPBACK)?"True":"False");
                auto ip = (u_char *) &((sockaddr_in *) a->addr)->sin_addr.s_addr;
                table->setText(rr, "ip", QString::asprintf("%d.%d.%d.%d", ip[0], ip[1], ip[2], ip[3]));
                if(a->netmask) {
                    ip = (u_char *) &((sockaddr_in *) a->netmask)->sin_addr.s_addr;
                    table->setText(rr, "netmask", QString::asprintf("%d.%d.%d.%d", ip[0], ip[1], ip[2], ip[3]));
                }
                if(a->broadaddr) {
                    ip = (u_char *) &((sockaddr_in *) a->broadaddr)->sin_addr.s_addr;
                    table->setText(rr, "broadaddr", QString::asprintf("%d.%d.%d.%d", ip[0], ip[1], ip[2], ip[3]));
                }
                if(a->dstaddr) {
                    ip = (u_char *) &((sockaddr_in *) a->dstaddr)->sin_addr.s_addr;
                    table->setText(rr, "dstaddr", QString::asprintf("%d.%d.%d.%d", ip[0], ip[1], ip[2], ip[3]));
                }
                if(device==0) device = dev;
            }
        }
    }
    pcap_freealldevs(devs);

    auto rowCnt = table->rowCount();
    if(rowCnt==0) {
        table->deleteLater();
        QMessageBox::critical(parent, "Error", "没找到 internet 设备");
        return QByteArray();
    } else if(rowCnt==1) {
        table->deleteLater();
        return table->item(0, "name")->text().toLocal8Bit();
    } else {
        auto dlg = new BaseDlg(parent);
        dlg->setAttribute(Qt::WA_DeleteOnClose);
        dlg->setWindowTitle("选择网卡");
        dlg->resize(900, 300);

        auto vBox = new QVBoxLayout(dlg->center);
        vBox->setContentsMargins(0,0,0,0);
        vBox->setSpacing(3);
        vBox->addSpacing(30);

        table->setDefs();
        table->setSelectionMode(QAbstractItemView::SingleSelection);
        table->horizontalHeader()->setSectionResizeMode(QHeaderView::ResizeToContents);
        if(! def.isEmpty()) for(int r=0; r<table->rowCount(); r++) if(table->item(r, "name")->text()==def) table->selectRow(r);
        QByteArray name;
        dlg->connect(table, &Table::cellDoubleClicked, dlg, [dlg, table, &name](int row) {
            name = table->item(row, "name")->text().toLocal8Bit();
            dlg->accept();
        });
        vBox->addWidget(table);

        auto hBox = new QHBoxLayout;
        hBox->addStretch();
        auto btnOk = new QPushButton("确定");
        btnOk->setMinimumWidth(80);
        dlg->connect(btnOk, &QPushButton::clicked, dlg, [dlg, table, &name] {
            auto sels = table->selectedRanges();
            if(sels.isEmpty()) {
                QMessageBox::warning(dlg, "Warning", "请选择网卡");
                return;
            }
            name = table->item(sels[0].topRow(), "name")->text().toLocal8Bit();
            dlg->accept();
        });
        hBox->addWidget(btnOk);

        hBox->addStretch();

        auto btnClose = new QPushButton("关闭");
        btnClose->setMinimumWidth(80);
        dlg->connect(btnClose, &QPushButton::clicked, dlg, &QDialog::reject);
        hBox->addWidget(btnClose);
        hBox->addStretch();

        vBox->addLayout(hBox);
        dlg->exec();
        return name;
    }
}


int sendMsg(QByteArray msg, const Resp &resp) {
    return sendMsgNet(msg, resp);
}

int sendMsgNet(QByteArray msg, const Resp &resp) {
    reThd->addResp(resp);
    return pcap_sendpacket(pcapSend, (u_char*)msg.data(), msg.size());
}
