text: /*
   * (C) Copyright 1996-2016 ECMWF.
   *
   * This software is licensed under the terms of the Apache Licence Version 2.0
   * which can be obtained at http://www.apache.org/licenses/LICENSE-2.0.
   * In applying this licence, ECMWF does not waive the privileges and immunities
   * granted to it by virtue of its status as an intergovernmental organisation nor
   * does it submit to any jurisdiction.
   */
  
  /*! \file MetaData.h
      \brief Implementation of the Template class MetaData.
  
      Magics Team - ECMWF 2006
  
      Started: Thu 5-Jan-2006
  
      Changes:
  
  */
  
  #include "MetaData.h"
  #include "Timer.h"
  
  #ifdef MAGICS_ON_WINDOWS
  #include "windux.h"
  #else
  #include <sys/resource.h>
  #include <sys/time.h>
  #endif
  
  
  using namespace magics;
  
  MetaDataVisitor::MetaDataVisitor() {
      meta_.push_back(this);
  }
  
  string MetaDataVisitor::start_;
  
  MetaDataVisitor::~MetaDataVisitor() {
      meta_.erase(std::remove(meta_.begin(), meta_.end(), this), meta_.end());
  }
  
  /*!
   Class information are given to the output-stream.
  */
  void MetaDataVisitor::print(ostream& out) const {
      out << "MetaData[";
      out << "]";
  }
  
  string now() {
      char tmp[256];
      timeval t;
      gettimeofday(&t, 0);
      sprintf(tmp, "%f", (t.tv_sec + t.tv_usec / 1000000.0));
      return string(tmp);
  }
  void MetaDataVisitor::start() {
      start_ = now();
  }
  
  void MetaDataVisitor::collectMetaData() {
      MagLog::dev() << "----MetaData::visit-----" << endl;
      parent_->visit(*this);
  
      try {
          ofstream out(profile_.c_str());
  
          out << "{\n\"timers\" : {" << endl;
  
          string s = "";
          for (vector<ProfileInfo>::const_iterator web = Timer::begin(); web != Timer::end(); ++web) {
              out << s;
              out << *web;
              s = ",\n";
          }
  #ifndef MAGICS_ON_WINDOWS  // windows doesn't support rusage
          struct rusage p;
          getrusage(RUSAGE_SELF, &p);
          out << "\n\t},\n\t\"start\": " << start_;
          out << ",\n\t\"stop\": " << now();
          out << ",\n\t\"general\": {" << endl;
          out << "\t\t\"user\" : " << p.ru_utime.tv_sec << "," << endl;
          out << "\t\t\"system\" : " << p.ru_stime.tv_sec << "," << endl;
          out << "\t\t\"memory\" : " << p.ru_maxrss / 1024 << "," << endl;
          out << "\t\t\"input\" : " << p.ru_inblock << "," << endl;
          out << "\t\t\"output\" : " << p.ru_oublock << endl;
          out << "\t}" << endl;
          out << "}" << endl;
  #endif
      }
  
      catch (...) {
          if (MagicsGlobal::strict()) {
              throw;
          }
      }
  
      if (!wms_file_.empty() && styles_.size()) {
          try {
              ofstream out(wms_file_);
  
  
              for (auto& style : styles_)
                  out << *style;
  
              out.close();
          }
          catch (...) {
              if (MagicsGlobal::strict()) {
                  throw;
              }
          }
      }
      if (!javascript_.empty()) {
          try {
              ofstream out(javascript_.c_str());
  
              out << "{";
  
              string s = "";
  
              for (map<string, string>::const_iterator web = web_.begin(); web != web_.end(); ++web) {
                  if (web->first == "world_file")
                      continue;
                  out << s;
                  out << "\"" << web->first << "\":" << web->second;
                  s = ",";
              }
  
              out << "}";
              out.close();
          }
          catch (...) {
              if (MagicsGlobal::strict()) {
                  throw;
              }
          }
      }
  
      if (!path_.empty()) {
          try {
              ofstream out(path_.c_str());
  
              out << "{";
  
              string s = "";
  
              for (map<string, string>::const_iterator web = web_.begin(); web != web_.end(); ++web) {
                  if (web->first == "world_file")
                      continue;
                  out << s;
                  out << "\"" << web->first << "\":" << web->second;
                  s = ",";
              }
  
              out << "}";
              out.close();
          }
          catch (...) {
              if (MagicsGlobal::strict()) {
                  throw;
              }
          }
      }
  
  
      if (!world_file_.empty()) {
          try {
              ofstream out(world_file_.c_str());
  
              for (map<string, string>::const_iterator web = web_.begin(); web != web_.end(); ++web) {
                  if (web->first != "world_file")
                      continue;
  
                  out << web->second;
              }
  
              out.close();
          }
          catch (...) {
              if (MagicsGlobal::strict()) {
                  throw;
              }
          }
      }
      if (!efi_.empty()) {
          char c;
          string path = buildSharePath("efi", efi_template_);
          try {
              ofstream out(efi_.c_str());
              ifstream in(path.c_str());
              while (in && in.get(c))
                  out.put(c);
              out.close();
              in.close();
          }
          catch (...) {
              ofstream out(efi_.c_str());
              out << " Could not opened " << path << endl;
              out.close();
              if (MagicsGlobal::strict()) {
                  throw;
              }
          }
      }
  }
  
  void MetaDataVisitor::metadata(map<string, string>& data) {
      string quote           = "\"";
      data["magics_version"] = quote + MAGICS_VERSION + quote;
      data["filename"]       = javascript_;
      parent_->visit(*this);
  }
  
  vector<MetaDataVisitor*> MetaDataVisitor::meta_;
  
  void MetaDataVisitor::collect() {
      for (vector<MetaDataVisitor*>::iterator meta = meta_.begin(); meta != meta_.end(); ++meta)
          (*meta)->collectMetaData();
  }
  
  #include "ContourLibrary.h"
  void StyleEntry::print(ostream& s) const {
      StyleLibrary styles = *WebLibrary::styles_;
  
      s << "{\"styles\": [ " << endl;
      string sep = "    ";
      for (auto style = styles_.begin(); style != styles_.end(); ++style) {
          string description = styles.getAttribute(*style, "contour_description", "description to come");
          string title       = styles.getAttribute(*style, "contour_title", "title to come");
          s << sep << "{\"name\":\"" << *style << "\"";
          sep = ",\n      ";
          s << sep << "\"description\":\"" << description << "\"";
          s << sep << "\"title\":\"" << title << "\"";
          s << sep << "\"legend\": { \"width\": 350";
          sep = ",\n          ";
          s << sep << "\"height\": 50 }";
          sep = "\n    ";
          s << sep << "}";
          sep = ",\n    ";
      }
      s << " 	  ]" << endl;
      s << "  }" << endl;
  }
  