#include <cdi.h>
#include <cstring>
#include <cstdlib>

#include "cdo_default_values.h"
#include "cdo_cdi_wrapper.h"

const char *
cdi_filetype2str(int filetype)
{
  switch (filetype)
    {
    // clang-format off
    case CDI_FILETYPE_GRB:  return "GRIB";
    case CDI_FILETYPE_GRB2: return "GRIB2";
    case CDI_FILETYPE_NC:   return "NetCDF";
    case CDI_FILETYPE_NC2:  return "NetCDF2";
    case CDI_FILETYPE_NC4:  return "NetCDF4";
    case CDI_FILETYPE_NC4C: return "NetCDF4 classic";
    case CDI_FILETYPE_NC5:  return "NetCDF5";
    case CDI_FILETYPE_SRV:  return "SERVICE";
    case CDI_FILETYPE_EXT:  return "EXTRA";
    case CDI_FILETYPE_IEG:  return "IEG";
    default:                return "";
    // clang-format on
    }
}

const char *
cdi_datatype2str(int datatype)
{
  static char str[20];
  str[0] = 0;
  if (datatype > 0 && datatype <= 32 ) snprintf(str, sizeof(str), "P%d", datatype);

  // clang-format off
  if      (datatype == CDI_DATATYPE_PACK  ) return "P0";
  else if (datatype > 0 && datatype <= 32 ) return str;
  else if (datatype == CDI_DATATYPE_CPX32 ) return "C32";
  else if (datatype == CDI_DATATYPE_CPX64 ) return "C64";
  else if (datatype == CDI_DATATYPE_FLT32 ) return "F32";
  else if (datatype == CDI_DATATYPE_FLT64 ) return "F64";
  else if (datatype == CDI_DATATYPE_INT8  ) return "I8";
  else if (datatype == CDI_DATATYPE_INT16 ) return "I16";
  else if (datatype == CDI_DATATYPE_INT32 ) return "I32";
  else if (datatype == CDI_DATATYPE_UINT8 ) return "U8";
  else if (datatype == CDI_DATATYPE_UINT16) return "U16";
  else if (datatype == CDI_DATATYPE_UINT32) return "U32";
  else                                      return "";
  // clang-format on
}

int
cdi_str2datatype(const char *datatypestr)
{
  int datatype = -1;
  size_t len = strlen(datatypestr);

  if (len > 1)
    {
      int ilen = atoi(datatypestr + 1);
      // clang-format off
      if (strncmp(datatypestr, "P0", len) == 0)          datatype = CDI_DATATYPE_PACK;
      else if (strncmp(datatypestr, "P", 1) == 0 && ilen > 0 && ilen <= 32) datatype = atoi(datatypestr + 1);
      else if (strncmp(datatypestr, "C32", len) == 0)    datatype = CDI_DATATYPE_CPX32;
      else if (strncmp(datatypestr, "C64", len) == 0)    datatype = CDI_DATATYPE_CPX64;
      else if (strncmp(datatypestr, "F32", len) == 0)    datatype = CDI_DATATYPE_FLT32;
      else if (strncmp(datatypestr, "F64", len) == 0)    datatype = CDI_DATATYPE_FLT64;
      else if (strncmp(datatypestr, "I8", len) == 0)     datatype = CDI_DATATYPE_INT8;
      else if (strncmp(datatypestr, "I16", len) == 0)    datatype = CDI_DATATYPE_INT16;
      else if (strncmp(datatypestr, "I32", len) == 0)    datatype = CDI_DATATYPE_INT32;
      else if (strncmp(datatypestr, "U8", len) == 0)     datatype = CDI_DATATYPE_UINT8;
      else if (strncmp(datatypestr, "U16", len) == 0)    datatype = CDI_DATATYPE_UINT16;
      else if (strncmp(datatypestr, "U32", len) == 0)    datatype = CDI_DATATYPE_UINT32;
      else if (strncmp(datatypestr, "real", len) == 0)   datatype = CDI_DATATYPE_FLT32;
      else if (strncmp(datatypestr, "double", len) == 0) datatype = CDI_DATATYPE_FLT64;
      // clang-format on
    }

  return datatype;
}

int
cdoTaxisCreate(int taxisType)
{
  if (CdoDefault::TaxisType != CDI_UNDEFID) taxisType = CdoDefault::TaxisType;
  return taxisCreate(taxisType);
}
