#!/usr/bin/env python
#
# fortnml
#
# ------------------------------------------------------------------------
# Copyleft 2009, Jesus Fernandez <jesusff IN THE DOMAIN gmail DOT com>
#
# Santader Meteorology Group, Universidad de Cantabria, Spain
#
# 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, either version 3 of the License, or
# (at your option) any later version.
#
# 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.
#
# You should have received a copy of the GNU General Public License
# along with this program.  If not, see <http://www.gnu.org/licenses/>.
# ------------------------------------------------------------------------

import sys
from fortran_namelist import *
from optparse import OptionParser

if __name__ == "__main__":
  def splitvar(varopt):
    if '@' in varopt:
      return varopt.split('@')
    else:
      return varopt, ""
  parser = OptionParser()
  parser.add_option(
    "-f", "--file", dest="namelist",
    help="Namelist file", metavar="NAMELIST"
  )
  parser.set_defaults(
    quiet=False, wrf=False, overwrite=False, trim=False,
    variable_a="", variable_s="", variable_m="", variable_d="",nitems=0
  )
  parser.add_option(
    "-q", "--quiet", action="store_true",
    help="Don't dump the namelist to stdout"
  )
  parser.add_option(
    "-w", "--wrf", action="store_true", default=False,
    help="WRF namelist.input parse mode"
  )
  parser.add_option(
    "-a", "--append", metavar="VARIABLE[@RECORD]", dest="variable_a",
    help="Append the provided values to this namelist entry. A specific record can be specified through variable@record syntax"
  )
  parser.add_option(
    "-r", "--record", metavar="RECORD", dest="thisrecord",
    help="Dump only the selected RECORD"
  )
  parser.add_option(
    "-s", "--set", metavar="VARIABLE[@RECORD]", dest="variable_s",
    help="Set the provided values to this namelist entry. A specific record can be specified through variable@record syntax"
  )
  parser.add_option(
    "-m", "--max-dom", metavar="VARIABLE[@RECORD]", dest="variable_m",
    help="Set the provided (single) value to this namelist entry as many times as the max_dom@domains specifies. WRF mode (--wrf) implied even if not set"
  )
  parser.add_option(
    "-n", metavar="NITEMS", dest="nitems", type='int',
    help="Repeat the value provided NITEMS times. Only used when in set (-s) or append (-a) mode"
  )
  parser.add_option(
    "--force-trim", metavar="NCOLS", dest="ncols", type='int',
    help="Force trimming the arrays in the namelist to a maximum of NCOLS items. Beware that this option trims every option, even those not limited by the max_dom entry, such as the eta_levels variable."
  )
  parser.add_option(
    "-d", "--delete", metavar="VARIABLE[@RECORD]", dest="variable_d",
    help="Delete a VARIABLE. The record can be specified through the VARIABLE@RECORD syntax"
  )
  parser.add_option(
    "-o", "--overwrite", action="store_true",
    help="Overwrite the provided namelist with the result"
  )
  parser.add_option(
    "-t", "--trim", action="store_true",
    help="Trim the length of the array variables to the maximum number of domains"
  )
  parser.add_option(
    "--no-math-expansion", action="store_false", dest="mathexp", default=True,
    help="Avoid solving math operations on the right-hand-side of the keywords. The default is to expand expressions such as interval_seconds = 24*3600. This behaviour is not appropriate when dealing with namelist.output files, where expressions such as H_MOM_ADV_ORDER = 11*5, have a different meaning."
  )
  parser.add_option(
    "--sort", action="store_true",
    help="Sort the records and options within each record in alphabetical order. This option is useful to compare to namelist which could be formatted in different order."
  )
  parser.add_option(
    "--no-wrf-checks", action="store_false", dest="wrfcheck", default=True,
    help="Avoid WRF checks and automagic modifications even if WRF mode was requested to recognize the max_dom option and trim the output or set multi-valued options."
  )
  (opt, args) = parser.parse_args()

  if not opt.namelist:
    sys.stderr.write("Missing namelist argument!")
    sys.exit()
  if (opt.variable_s or opt.variable_a or opt.variable_m) and not args:
    sys.stderr.write("Missing values to set/append!")
    sys.exit()
  if opt.variable_m or opt.trim:
    opt.wrf = True
  if opt.wrf:
    nml = WrfNamelist(opt.namelist, opt.mathexp)
  else:
    nml = FortranNamelist(opt.namelist, opt.mathexp)

  if opt.variable_s:
    variable, record = splitvar(opt.variable_s)
    if opt.nitems:
      args = [args[0] for i in range(opt.nitems)]
    nml.setValue(variable, coerce_value_list(args, opt.mathexp), record)
  elif opt.variable_a:
    variable, record = splitvar(opt.variable_a)
    if opt.nitems:
      args = [args[0] for i in range(opt.nitems)]
    nml.appendValue(variable, coerce_value_list(args, opt.mathexp), record)
  elif opt.variable_m:
    variable, record = splitvar(opt.variable_m)
    nml.setMaxDomValue(variable, args[0], record)
  elif opt.variable_d:
    variable, record = splitvar(opt.variable_d)
    nml.delVariable(variable, record)

  if opt.trim or opt.ncols:
    nml.trimMaxDom(opt.ncols)
  if opt.wrf and opt.wrfcheck:
    nml.wrfCheck()
  if opt.overwrite:
    nml.overWriteNamelist()
  elif not opt.quiet:
    if opt.thisrecord:
      sys.stdout(nml.printNamelist(opt.thisrecord, sorted=opt.sort))
    else:
      sys.stdout(nml.printNamelist(sorted=opt.sort))
