#include<Python.h>
#include <QCoreApplication>
#include<iostream>
#include<Eigen/Dense>
#include"advanced.h"

#include<numbers>
#include<random>
#include<QSettings>  
#include<math.h>
#include<cmath>

#include <cstring>  
#include <QFile>
#include <QTextStream>
#include <QDir>

complex_t QString2Complex(QString str)
{
	QString real;
	while (!str.isEmpty()) {
		QChar c = str.front();
		if (c != '|')
			real.push_back(c);
		str.remove(0, 1);
		if (c == '|')
			break;
	}
	return complex_t(real.toDouble(), str.toDouble());
}

Eigen::Vector3d QString2Double(QString str)
{
	Eigen::Vector3d r;
	int iIndex = 0;
	QString complex;

	for (size_t i = 0; i < str.size(); i++)
	{
		if (str.at(i) == '|') {
			switch (iIndex)
			{
			case 0:
				r(0) = complex.toDouble();
				break;
			case 1:
				r(1) = complex.toDouble();
				break;
			case 2:
				r(2) = complex.toDouble();
				break;
			default:
				break;
			}
			iIndex++;
			complex.clear();
		}
		else {
			complex.push_back(str.at(i));
		}
	}
	return r;
}


int main(int argc, char* argv[])
{
	QCoreApplication a(argc, argv);
	//保留下参数，进行校验
	QString curPath = QDir::currentPath();
	QString filepath = curPath.append("\\..\\..\\builder_sample\\py_builder.py");

	QFile file(filepath);
	if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) {
		return 2;
	}
	QTextStream in(&file);
	QString content = in.readAll(); // 读取整个文件内容  

	//先执行下python环境
	Py_Initialize();

	if (!Py_IsInitialized())
	{
		return -1;
	}

	// 执行Python代码
	int result = PyRun_SimpleString(content.toStdString().c_str());

	Py_Finalize();

	curPath = QDir::currentPath();
	QString configFile= curPath.append("\\complex_strings.ini");
	QSettings settings(configFile, QSettings::IniFormat);
	QString sample = "sample";
	tbplas::builder::SK sk;

	//测试dd
	for (size_t i = 0; i < 1000; i++)
	{
		sample = "dd";
		sample.append(QString::number(i, 10));
		QString r = settings.value(sample + "/r").toString();
		QString label_i = settings.value(sample + "/label_i").toString();
		QString label_j = settings.value(sample + "/label_j").toString();
		QString v_dds = settings.value(sample + "/v_dds").toString();
		QString v_ddp = settings.value(sample + "/v_ddp").toString();
		QString v_ddd = settings.value(sample + "/v_ddd").toString();
		QString result = settings.value(sample + "/result").toString();
		complex_t out = sk.dd(QString2Double(r), label_i.toStdString(), label_j.toStdString(),
			QString2Complex(v_dds), QString2Complex(v_ddp), QString2Complex(v_ddd));
		complex_t out2 = QString2Complex(result);
		if (fabs(out.real() - out2.real()) < 0.000000000000001 &&
			fabs(out.real() - out2.real()) < 0.000000000000001)
		{
			std::cout << "pass :" << sample.toStdString() << std::endl;
		}
		else {
			std::cout << "err :" << sample.toStdString() << std::endl;
		}
	}
	//测试pd
	for (size_t i = 0; i < 1000; i++)
	{
		sample = "pd";
		sample.append(QString::number(i, 10));
		QString r = settings.value(sample + "/r").toString();
		QString label_p = settings.value(sample + "/label_p").toString();
		QString label_d = settings.value(sample + "/label_d").toString();
		QString v_dds = settings.value(sample + "/v_dds").toString();
		QString v_ddp = settings.value(sample + "/v_ddp").toString();
		QString result = settings.value(sample + "/result").toString();
		complex_t out = sk.pd(QString2Double(r), label_p.toStdString(), label_d.toStdString(),
			QString2Complex(v_dds), QString2Complex(v_ddp));
		complex_t out2 = QString2Complex(result);
		if (fabs(out.real() - out2.real()) < 0.00000001 &&
			fabs(out.real() - out2.real()) < 0.00000001)
		{
			std::cout << "pass :" << sample.toStdString() << std::endl;
		}
		else {
			std::cout << "err :" << sample.toStdString() << std::endl;
		}
	}
	//测试pp
	for (size_t i = 0; i < 1000; i++)
	{
		sample = "pp";
		sample.append(QString::number(i, 10));
		QString r = settings.value(sample + "/r").toString();
		QString label_i = settings.value(sample + "/label_i").toString();
		QString label_j = settings.value(sample + "/label_j").toString();
		QString v_pps = settings.value(sample + "/v_pps").toString();
		QString v_ppp = settings.value(sample + "/v_ppp").toString();
		QString result = settings.value(sample + "/result").toString();
		complex_t out = sk.pp(QString2Double(r), label_i.toStdString(), label_j.toStdString(),
			QString2Complex(v_pps), QString2Complex(v_ppp));
		complex_t out2 = QString2Complex(result);
		if (fabs(out.real() - out2.real()) < 0.00000001 &&
			fabs(out.real() - out2.real()) < 0.00000001)
		{
			std::cout << "pass :" << sample.toStdString() << std::endl;
		}
		else {
			std::cout << "err :" << sample.toStdString() << std::endl;
		}
	}

	return a.exec();
}
