
#include "cutout.hpp"
#include "cutout_nljson.hpp"
#include "mcutout.hpp"
#include "mcutout_nljson.hpp"

#include "json.hpp"
#include <string>

using json = nlohmann::json;

/* All nlohmann-json exception are json::exception <- std::exception.
 * So let them be caught by std::excpetion as 'Internal errors' in rpc-call's infinite loop,
 * assuming all API syntactic errors were caught in servlet API parser */

enum service {SEARCH, CUTOUT, MCUTOUT, MERGEF, MERGE1, MERGE2, MERGE3, SUBIMG};

class json_request
{
   public:

      json_request(std::string request_json);

      bool is_search() {return m_service == SEARCH;}
      bool is_cutout() {return m_service == CUTOUT;}
      bool is_mcutout() {return m_service == MCUTOUT;}
      bool is_mergefiles() {return m_service == MERGEF;}
      bool is_mergefiles_common_header() {return m_service == MERGE1;}
      bool is_mergefiles_reproject() {return m_service == MERGE2;}
      bool is_mergefiles_add_reprojected() {return m_service == MERGE3;}
      bool is_subimg() {return m_service == SUBIMG;}

      std::string pubdid() {return m_jservice.at("pubdid");}

      struct coordinates coordinates();

      bool count_null_values(){return m_jservice.at("count_null_values");}

      std::vector<struct cut_param_s> cut_params();

      std::string merge_id() {return m_jservice.at("merge_id");}
      std::string dimensionality() {return m_jservice.at("dimensionality");}
      std::vector<std::string> files_to_merge() {return m_jservice.at("files_to_merge");}
      std::string fitsfilename() {return m_jservice.at("fits_filename");}

      /* SUBIMG */

      std::string abs_subimg_pathname() {return m_jservice.at("subimg_filename");}
      std::string img_pathname()    {return m_jservice.at("img_pathname");}
      int         img_hdunum()      {return m_jservice.at("img_hdunum");}
      std::vector<struct fits_card> extra_cards();

      /* new: no coordinates instead separate pos band time pol */

      position     get_pos()  { return (m_jservice.contains("pos")  ? (position)    m_jservice.at("pos")  : pos_none ); }
      band         get_band() { return (m_jservice.contains("band") ? (band)        m_jservice.at("band") : band_none); }
      time_axis        get_time() { return (m_jservice.contains("time") ? (time_axis)       m_jservice.at("time") : time_none); }
      std::vector<std::string> get_pol();

   private:
      json m_jservice;
      service m_service;
};
