/*
  This file is part of CDO. CDO is a collection of Operators to
  manipulate and analyse Climate model Data.

  Copyright (C) 2003-2019 Uwe Schulzweida, <uwe.schulzweida AT mpimet.mpg.de>
  See COPYING file for copying and redistribution conditions.

  This program is free software; you can redistribute it and/or modify
  it under the terms of the GNU General Public License as published by
  the Free Software Foundation; version 2 of the License.

  This program is distributed in the hope that it will be useful,
  but WITHOUT ANY WARRANTY; without even the implied warranty of
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  GNU General Public License for more details.
*/

/*
   This module contains the following operators:

*/

#include "cdi.h"

#include "cdo_int.h"
#include "parse_literals.h"
#include "pmlist.h"
#include "util_string.h"

static void
printValues(const int nvalues, const std::vector<std::string> &values)
{
  char fltstr[128];
  if (nvalues)
    {
      const int dtype = literalsFindDatatype(nvalues, values);
      for (int i = 0; i < nvalues; ++i)
        {
          const char *value = values[i].c_str();
          if (i) printf(", ");
          switch (dtype)
            {
            case CDI_DATATYPE_INT8: printf("%db", literal_to_int(value)); break;
            case CDI_DATATYPE_INT16: printf("%ds", literal_to_int(value)); break;
            case CDI_DATATYPE_INT32: printf("%d", literal_to_int(value)); break;
            case CDI_DATATYPE_FLT32:
              printf("%sf", double_to_attstr(Options::CDO_flt_digits, fltstr, sizeof(fltstr), literal_to_double(value)));
              break;
            case CDI_DATATYPE_FLT64:
              printf("%s", double_to_attstr(Options::CDO_dbl_digits, fltstr, sizeof(fltstr), literal_to_double(value)));
              break;
            default: printf("\"%s\"", value);
            }
        }
    }
}

void
kvldump(const PMList &pmlist)
{
  for (const auto &kvlist : pmlist)
    {
      const char *listname = kvlist.name.c_str();
      if (listname) printf("&%s\n", listname);
      for (const auto &kv : kvlist)
        {
          const char *key = kv.key.c_str();
          if (listname) printf("  ");
          printf("%s = ", key);
          printValues(kv.nvalues, kv.values);
          printf("\n");
        }
      if (listname) printf("/\n");
    }
}

void *
Nmldump(void *process)
{
  cdoInitialize(process);

  const int NMLDUMP = cdoOperatorAdd("nmldump", 0, 0, nullptr);
  const int KVLDUMP = cdoOperatorAdd("kvldump", 0, 0, nullptr);

  const int operatorID = cdoOperatorID();

  PMList pmlist;
  pmlist.readNamelist(stdin, "STDIN");

  if (operatorID == NMLDUMP)
    pmlist.print();
  else if (operatorID == KVLDUMP)
    kvldump(pmlist);

  cdoFinish();

  return nullptr;
}
