
#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 "io.hpp"
#include "my_assert.hpp"

#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
      {
         unsigned long i = 0;
         unsigned long hdr_len = hd.m_header.length();
         while((i*80+80) <= hdr_len)
         {
            cout << hd.m_header.substr(80*i++, 80) << endl;
         }
      }
      // FIXME remove all explicit cout cerr to main.cpp and here use ostream&

   }

   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;
}


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;
}


