/*
 * (c) Copyright 2018 CORSIKA Project, corsika-project@lists.kit.edu
 *
 * See file AUTHORS for a list of contributors.
 *
 * This software is distributed under the terms of the GNU General Public
 * Licence version 3 (GPL Version 3). See file LICENSE for a full version of
 * the license.
 */

#include <catch2/catch.hpp>

#include <corsika_data/Interface.h>

#include <iostream>
#include <array>
using namespace std;

using namespace corsika_data;

const array<double, 3*9> testData = {0.00000000,       0.00000000,       0.00000000,       
				     0.00000000,       0.00000000,       0.00000000,
				     0.00000000,       0.00000000,       0.00000000,
				     7.74900036E-06,   1.00000000,       1.47967212E-05,
				     3.76063472E-05,   3.91302201E-05,   5.68050455E-05,
				     5.91166172E-05,   6.64338659E-05,   8.79753206E-05,
				     9.61698461E-05,   1.02615748E-04,   1.12829475E-04,
				     1.28208514E-04,   1.50734515E-04,   1.79381183E-04,
				     2.09064019E-04,   2.32736333E-04,   2.50067125E-04};

const std::string fileName = std::string(TESTDATA);
const std::string fileNameBZ2 = std::string(TESTDATA)+std::string(".bz2");


TEST_CASE ("Data", "[data]") {

#ifdef TEST_WITH_BOOST

  SECTION ("c++, uncompressed") {
    bool b = CorDataCanDeCompress();
    CHECK( b==true );
    cout << "Reading: " << fileName << endl;
    CorDataOpenFile(fileName);
    std::string str;
    CorDataNextText(str);
    CHECK ( str=="sibyll20" );
    CHECK ( CorDataNextNumber()==0.10000E-02 );
    CHECK ( CorDataNextNumber()==91 );
    CHECK ( CorDataNextNumber()==261 );
    CHECK ( CorDataNextNumber()==5 );
    CHECK ( CorDataNextNumber()==11 );
    CHECK ( CorDataNextNumber()==20 );

    double aData[3*9];
    const int length = 3*9;
    CorDataFillArray(aData, length);

    for (int i=0; i<length; ++i) {
      CHECK( aData[i] == testData[i] );
    }    
    CorDataCloseFile();
  }
  
  SECTION ("c++, compressed") {
    bool b = CorDataCanDeCompress();
    CHECK( b==true );
    cout << "Reading: " << fileNameBZ2 << endl;
    CorDataOpenFile(fileNameBZ2);
    std::string str;
    CorDataNextText(str);
    CHECK ( str=="sibyll20" );
    CHECK ( CorDataNextNumber()==0.10000E-02 );
    CHECK ( CorDataNextNumber()==91 );
    CHECK ( CorDataNextNumber()==261 );
    CHECK ( CorDataNextNumber()==5 );
    CHECK ( CorDataNextNumber()==11 );
    CHECK ( CorDataNextNumber()==20 );

    double aData[3*9];
    const int length = 3*9;
    CorDataFillArray(aData, length);

    for (int i=0; i<length; ++i) {
      CHECK( aData[i] == testData[i] );
    }    
    CorDataCloseFile();
  }
  
  SECTION ("fortran, uncompressed") {
    bool b = cordatacandecompress_();
    CHECK( b==true );
    cout << "Reading: " << fileName << endl;
    cordataopenfile_(fileName.c_str());
    char str[10];
    cordatanexttext_(str, 10);
    CHECK ( std::string(str)=="sibyll20" );
    CHECK ( cordatanextnumber_()==0.10000E-02 );
    CHECK ( cordatanextnumber_()==91 );
    CHECK ( cordatanextnumber_()==261 );
    CHECK ( cordatanextnumber_()==5 );
    CHECK ( cordatanextnumber_()==11 );
    CHECK ( cordatanextnumber_()==20 );

    double aData[3*9];
    const int length = 3*9;
    cordatafillarray_(aData, length);
    
    for (int i=0; i<length; ++i) {
      CHECK( aData[i] == testData[i] );
    }    
    cordataclosefile_();
  }

  SECTION ("fortran, compressed") {
    bool b = cordatacandecompress_();
    CHECK( b==true );
    cout << "Reading: " << fileNameBZ2 << endl;
    cordataopenfile_(fileNameBZ2.c_str());
    char str[10];
    cordatanexttext_(str, 10);
    CHECK ( std::string(str)=="sibyll20" );
    CHECK ( cordatanextnumber_()==0.10000E-02 );
    CHECK ( cordatanextnumber_()==91 );
    CHECK ( cordatanextnumber_()==261 );
    CHECK ( cordatanextnumber_()==5 );
    CHECK ( cordatanextnumber_()==11 );
    CHECK ( cordatanextnumber_()==20 );

    double aData[3*9];
    const int length = 3*9;
    cordatafillarray_(aData, length);
    
    for (int i=0; i<length; ++i) {
      CHECK( aData[i] == testData[i] );
    }    
    cordataclosefile_();
  }

#else

  SECTION ("c++") {
    CHECK_THROWS( CorDataOpenFile("") );
    double a[1];
    const int length = 1;
    CHECK_THROWS( CorDataFillArray(a, length) );
    CHECK_THROWS( CorDataCloseFile() );
    double v = 0;
    CHECK_THROWS( v = CorDataNextNumber() );
    string data;
    CHECK_THROWS( CorDataNextText(data) );
    CHECK( CorDataCanDeCompress() == false );
  }
  
  SECTION ("fortran") {
    CHECK_THROWS( cordataopenfile_("") );
    double a[1];
    const int length = 1;
    CHECK_THROWS( cordatafillarray_(a, length) );
    CHECK_THROWS( cordataclosefile_() );
    double d = 0;
    CHECK_THROWS( d = cordatanextnumber_() );
    char* str = "";
    CHECK_THROWS( cordatanexttext_(str, 0) );
    CHECK( cordatacandecompress_() == 0 );
  }
  
#endif
}