
#include "ast.hpp"

#include "ast4vl.hpp" // cout operator needed
#include "cutout.hpp" // coordinates needed
#include "cutout_ostream.hpp"
#include "service_string.hpp"
#include "fitsfiles.hpp" // header-string needed
#include "json_request.hpp" // uses json for vlkb-overlap region-string

#include "io.hpp"
#include "my_assert.hpp"

#include "ast_frameset.hpp" // FIXME temporarily was moved common/src -> common/include


#include <iostream>
#include <climits> // INT_MAX needed
#include <sstream>
#include <vector>


using namespace std;




//---------------------------------------------------------------------
// vertices
//---------------------------------------------------------------------

int vlkb_skyvertices(const string& pathname, const string& skysys_str)
{
   LOG_trace(__func__);

   int maxHdu = 1;// FIXMEINT_MAX; // read all HDU's

   std::vector<fitsfiles::Hdu> allHdus =
      fitsfiles::fname2hdrstr(pathname, maxHdu);

   for(unsigned int i=0; i<allHdus.size(); i++)
   {
      cout << "HDU#" << i << endl;

      fitsfiles::Hdu hd = allHdus.at(i);

      vector<point2d> vertices = calc_skyvertices(hd.m_header, skysys_str);

      for(point2d vertex : vertices) cout << " " << vertex << endl;
   }

   return 0;
}



//---------------------------------------------------------------------
// bounds
//---------------------------------------------------------------------
/*
const string VELOLSRK{"System=VELO,StdOfRest=LSRK,Unit=km/s"};
const string WAVEBARY{"System=WAVE,StdOfRest=Bary,Unit=m"};
*/
int vlkb_listbounds(const string& skysys_str, const string& specsys_str, const string& pathname)
{
   LOG_trace(__func__);

   int maxHdu = 1;//FIXME INT_MAX; // read all HDU's

   std::vector<fitsfiles::Hdu> allHdus =
      fitsfiles::fname2hdrstr(pathname, maxHdu);

   for(unsigned int i=0; i<allHdus.size(); i++)
   {
      cout << "HDU#" << i << endl;

      fitsfiles::Hdu hd = allHdus.at(i);

      vector<Bounds> bounds_vec = calc_bounds(hd.m_header, skysys_str, specsys_str);

      for(Bounds bnds : bounds_vec) cout << bnds << endl;
   }

   return 0;
}




//---------------------------------------------------------------------
// header backup and modif
//---------------------------------------------------------------------
/*
const string VELOLSRK{"System=VELO,StdOfRest=LSRK,Unit=km/s"};
const string WAVEBARY{"System=WAVE,StdOfRest=Bary,Unit=m"};
*/

void write_previous(string header, string filename)
{
   std::ofstream out(filename);
   out << header;
}


int header_backup(const string& pathname, bool backup)
{
   LOG_trace(__func__);

   int maxHdu = 1;//FIXME INT_MAX; // read all HDU's

   std::vector<fitsfiles::Hdu> allHdus =
      fitsfiles::fname2hdrstr(pathname, maxHdu);

   for(unsigned int i=0; i<allHdus.size(); i++)
   {
      cerr << "HDU#" << i << endl;

      fitsfiles::Hdu hd = allHdus.at(i);

      if(backup)
         write_previous(hd.m_header, pathname +"hdr" + ((i>0) ? "#" + to_string(i+1)  : "") );
      else
         cout << hd.m_header << endl;

      // FIXME remove all explicit cout cerr to main.cpp and here use ostream&

   }

   return 0;
}


int header_modif_coordsys(const string& skysys_str, const string& specsys_str, const string& pathname)
{
   LOG_trace(__func__);

   int maxHdu = 1;//FIXME INT_MAX; // read all HDU's

   std::vector<fitsfiles::Hdu> allHdus =
      fitsfiles::fname2hdrstr(pathname, maxHdu);

   for(unsigned int i=0; i<allHdus.size(); i++)
   {
      cerr << "HDU#" << i << endl;

      fitsfiles::Hdu hd = allHdus.at(i);

      write_previous(hd.m_header, "backup.fitshdu"+ to_string(i) +"header.orig");
      ast::frameset frm_set(hd.m_header);
      frm_set.set_skysystem(skysys_str); 
      if(frm_set.has_specframe())
         frm_set.set_specsystem(specsys_str);

      //frm_set.write(cout, hd.m_header);
      frm_set.write2(pathname, i+1);
   }

   return 0;
}




//---------------------------------------------------------------------
// overlap with area given in query-string form (name=value&...)
//---------------------------------------------------------------------

// parse query string to service::coordinates

vector<string> split (const string &s, char delim)
{
   vector<string> result;
   stringstream ss (s);
   string item;

   while (getline (ss, item, delim)) {
      result.push_back (item);
   }

   return result;
}


coordinates parse_coordinates(const string region_string)
{
   LOG_trace(string(__func__) + " : " + region_string);

   json_request req(region_string);
   coordinates coord = to_coordinates(req.get_pos(), req.get_band(), req.get_time(), req.get_pol());

   LOG_STREAM << "coord parsed: " << coord << endl;

   return coord;
}


int vlkb_overlap(const string& pathname, const string& region, vector<uint_bounds>& bnds) 
{
   LOG_trace(__func__);

   int maxHdu = 1;// INT_MAX; FIXME fitsfiles::header throws error reading behind end-of-file due to INT_MAX 

   std::vector<fitsfiles::Hdu> allHdus =
      fitsfiles::fname2hdrstr(pathname, maxHdu);

   const coordinates coord = parse_coordinates(region.c_str());

   int ov_code;
   for(unsigned int i=0; i<allHdus.size(); i++)
   {
      fitsfiles::Hdu hd = allHdus.at(i);
      bnds = calc_overlap(hd.m_header, coord, ov_code);
   }
   return ov_code;
}


