#include "YODA/Estimate.h"
#include "YODA/Utils/MetaUtils.h"
#include "YODA/Utils/MathUtils.h"
#include <cmath>
#include <fstream>

using namespace YODA;

//TestHelpers::TestData testData;

auto testEstimate() {
  Estimate e1;

  // Set central value / error
  e1.setVal(42);
  e1.setErr({-4,5});
  e1.setErr({2,-3}, "syst");
  e1.setErr({-1,2}, "stats");

  if (e1.val() != 42)  return CHECK_TEST_RES(false);
  std::pair<double,double> errDU = e1.errDownUp();
  if (errDU.first != -4 || errDU.second != 5)  return CHECK_TEST_RES(false);
  std::pair<double,double> errNP = e1.errNegPos("syst");
  if (errNP.first != -3 || errNP.second != 2)  return CHECK_TEST_RES(false);
  if (e1.errNeg("stats") != -1 || e1.errPos("stats") != 2)  return CHECK_TEST_RES(false);

  Estimate e2(2, {6,-8});
  if (e2.relErrDown() != 3 || e2.relErrUp() != -4)  return CHECK_TEST_RES(false);
  if (e2.valMax() != 8 || e2.valMin() != -6)        return CHECK_TEST_RES(false);

  Estimate e3(2, {-6,8}, "syst1");
  e3.setErr({-8,6}, "syst2");
  if (e3.totalErr().first != -10 || e3.totalErr().second != 10)  return CHECK_TEST_RES(false);
  if (e3.quadSum().first != -10 || e3.quadSum().second != 10)  return CHECK_TEST_RES(false);

  Estimate e4 = e3 + Estimate(2, {-8,6}, "syst1");
  if (e4.val() != 4)  return CHECK_TEST_RES(false);
  std::pair<double,double> errDU2 = e4.errDownUp("syst1");
  if (errDU2.first != -14 || errDU2.second != 14)  return CHECK_TEST_RES(false);
  std::pair<double,double> errDU3 = e4.errDownUp("syst2");
  if (errDU3.first != -8 || errDU3.second != 6)  return CHECK_TEST_RES(false);

  e3.setErr({-3,3}, "cor,syst3");
  Estimate e5 = e3 + Estimate(3, {-4,4}, "cor,syst3");
  if (e5.val() != 5)  return CHECK_TEST_RES(false);
  std::pair<double,double> errDU4 = e5.errDownUp("cor,syst3");
  if (errDU4.first != -7 || errDU4.second != 7)  return CHECK_TEST_RES(false);

  Estimate e6 = e3 - Estimate(3, {-4,4}, "cor,syst3");
  if (e6.val() != -1)  return CHECK_TEST_RES(false);
  std::pair<double,double> errDU5 = e6.errDownUp("cor,syst3");
  if (errDU5.first != -7 || errDU5.second != 7)  return CHECK_TEST_RES(false);

  e6.scale(10);
  if (e6.val() != -10)  return CHECK_TEST_RES(false);
  std::pair<double,double> errDU6 = e6.errDownUp("cor,syst3");
  if (errDU6.first != -70 || errDU6.second != 70)  return CHECK_TEST_RES(false);

  return CHECK_TEST_RES(true);
}


int main() {

  int rtn = CHECK_TEST_RES( testEstimate() == EXIT_SUCCESS );

  return rtn;
}
