# $Id: importNOS_CurSubs.rb 7144 2019-12-28 00:18:08Z flaterco $
# Functions for importNOS.rb:
# Current subordinate station import

def importCurSubs(db)

  # The undocumented MDAPI (1.0) geogroup children query (getting stations)
  # does not work for currents.  In lieu of that, geogroups are parsed out of
  # the old style station list web pages by parse-oldcurlists.rb and left in
  # the table currents_geogroups.  This needn't be done if there are no new
  # stations.  getCurrentsGeogroups returns an empty hash if the table is not
  # present.
  currentsGeogroups = getCurrentsGeogroups(db)

  currents = readCurJson()
  File.open("renamings-cursubs.sql","w") {|renamings|
    currents.each {|csta|

      raise "Notices are not null anymore" unless csta["notices"].nil?
      raise "Disclaimers are not null anymore" unless csta["disclaimers"].nil?

      offsets = csta["currentpredictionoffsets"]
      shortrefsid = offsets["refStationId"]

      next if shortrefsid.empty?

      shortsid = csta["id"]
      sidp = shortsid + "_" + csta["currbin"].to_s
      refsidp = shortrefsid + "_" + offsets["refStationBin"].to_s
      cname = csta["name"]

      # Demand exactly one ref station with refsidp
      # Count 0  - silently skip this sub.
      # Count 1  - good.
      # Count >1 - throw.
      if !refStationExists(db, refsidp)
	refsidp.upcase!
	next if !refStationExists(db, refsidp)
      end
      refIndex = getRefIndex(db,refsidp)  # Throws on count != 1

      # type is H, S, W, or Y.
      #   H = harmonic
      #   S = subordinate
      #   W = weak and variable with null offsets
      #   Y = undocumented ?  Is that like X only 1 more?
      # Current refs have records saying type H, null offsets, and their own
      # ID in the refStationId field.
      type = csta["type"]
      case type
      when "H", "W"
	next
      when "S"
	# proceed
      else
	print cname, " is type ", type, "; not handled\n"
	raise "Unknown type not handled"
      end

      # isMaybeNotFreeData - without using geogroup.
      # There was a list of 7 hard-coded names in importNOSSC.pgcc, so guess
      # what?
      # Throw out some B.C. subordinate current stations (on Wrangell).
      if ["PCT2576_1", "PCT2586_1", "PCT2591_1", "PCT2601_1", "PCT2606_1",
	  "PCT2611_1", "PCT2616_1"].include?(sidp)
	print "Skipped ", sidp, " ", cname, "\n"
	next
      end

      # Unlike the analogous functions used in importNOS_TideSubs.rb, these
      # throw if count > 1.
      oldtuple = getRefNameStateCountryTzUnits(db, sidp)
      oldtuple = getOldCurSubFields(db, sidp) if oldtuple.nil?
      if oldtuple.nil?
	# ***
	# This is only good enough to handle the new stations around Puget
	# Sound that appeared 2019-12.  Anything outside of Washington State is
	# rejected to avoid accidental reuse.

	unless currentsGeogroups.include?(shortsid)
	  raise "Need geogroup for #{shortsid}"
	end
	state, region, subregion = currentsGeogroups[shortsid]
	unless state == "Washington"
	  raise "Unexpected state retrieved from currents_geogroups"
	end
	state = "WA"
	country = "USA"
	tz = ":America/Los_Angeles"
	units = getUnitsFromRef(db,refIndex)

	name = cname
	# depthType is B, S, or U.
	#   B = below chart datum
	#   S = below surface
	#   U = unknown
	depth_ft = csta["depth"]
	name += " (Depth " + depth_ft.to_i.to_s + "ft)" unless depth_ft.nil?
	namestub = name
	name += ", " + subregion if !subregion.nil? && !name.include?(subregion)
	name += ", " + region if !region.nil? && !name.include?(region)
	name += ", Washington Current"
	if name.length > 89 # PCT1401_1 and PCT2191_1
	  raise "Subregion isn't nil" unless subregion.nil?
	  name = namestub + ", Washington Current"
	end
      else
	name, state, country, tz, units = oldtuple
      end
      raise "State might be nil but should not be empty" if !state.nil? and state.empty?
      name = name.gsub("D.C.","DC").gsub("F.S.M.","FSM")
      name = name.chomp(" (2)").chomp(" (sub)")

      # Western Aleutians longitude errors are not checked for here.
      lat = csta["lat"]
      lng = csta["lng"]

      mindir = offsets["meanEbbDir"]    # degrees true
      maxdir = offsets["meanFloodDir"]  # degrees true
      mint   = offsets["mecTimeAdjMin"] # minutes
      maxt   = offsets["mfcTimeAdjMin"] # minutes
      sbft   = offsets["sbfTimeAdjMin"] # minutes
      sbet   = offsets["sbeTimeAdjMin"] # minutes
      minlm  = offsets["mecAmpAdj"]     # multiplier
      maxlm  = offsets["mfcAmpAdj"]     # multiplier

      raise "Nil offsets" if mint.nil? or maxt.nil? or sbft.nil? or
	sbet.nil? or minlm.nil? or maxlm.nil?

      fixednulls = false
      notes = nil
      legal = nil
      minlm, fixednulls = [0.001, true] if minlm <= 0
      maxlm, fixednulls = [0.001, true] if maxlm <= 0
      if fixednulls
	print "Fixed null multipliers at ", sidp, " ", name, "\n"
	notes = "Velocities for this station should be disregarded--use times only.\n";
	legal = "IGNORE VELOCITIES";
      end

      # Time warps and other meridian problems
      # (begin near-duplication of code from TideSubs)
      submerid = TZmerids[tz]
      if submerid.nil?
	print "Missing from TZmerids: ", tz, "\n"
	raise "Missing tz"
      end
      reftz = getRefTimezone(db, refsidp)
      if reftz != tz
	refmerid = TZmerids[reftz]
	if refmerid.nil?
	  print "Missing from TZmerids: ", reftz, "\n"
	  raise "Missing tz"
	end
	if refmerid != submerid
	  print "Time warp at ", sidp, " ", name, "\n"
	  print "  Ref ", refsidp, " is ", reftz, " (merid ", refmerid, ")\n"
	  print "  Sub is ", tz, " (merid ", submerid, ")\n"
	  adjustMin = (refmerid - submerid) * 60
	  mint += adjustMin
	  maxt += adjustMin
	  sbft += adjustMin
	  sbet += adjustMin
	  notes = append(notes, "Reference is in time zone " + reftz +
			 "; adjusted offsets " + (refmerid-submerid).to_s +
			 " hr\nto undo LST compensation.\n")
	end
      end

      # Resolve name clashes
      if refStationNamed(db, name)
	name += " (sub)"
	if nameInUse(db, name)
	  raise "Adding sub wasn't enough"
	end
      elsif nameInUse(db, name)
	stupidSuffixNumber = 1
	begin
	  stupidSuffixNumber += 1
	  tryname = name + " (" + stupidSuffixNumber.to_s + ")"
	end while nameInUse(db, tryname)
	name = tryname
      end
      raise "Name got too long: #{name}" if name.length > 89

      xfields = "Credit:NOAA data processed by David Flater for XTide\n https://flaterco.com/xtide/"

      if oldtuple.nil?
	mname = mangle(name)
	renamings.print "-- #{sidp}\n-- #{cname}\n-- lat #{lat} lon #{lng}\nupdate data_sets\n  set name = '#{mname}'\n  where name = '#{mname}';\n"
      end

      mint = mint.to_s + " minutes"
      maxt = maxt.to_s + " minutes"
      sbft = sbft.to_s + " minutes"
      sbet = sbet.to_s + " minutes"
      comments = nil              # Saved for future use
      res = db.exec("insert into data_sets (name, original_name, station_id_context, station_id, lat, lng, timezone, state, country, units, source, legalese, notes, comments, restriction, xfields, ref_index, min_time_add, min_level_multiply, max_time_add, max_level_multiply, flood_begins, ebb_begins, min_dir, max_dir) values ($1, $2, 'NOS', $3, $4, $5, $6, $7, $8, $9, 'CO-OPS Metadata API', $10, $11, $12, 'Public domain', $13, $14, $15, $16, $17, $18, $19, $20, $21, $22)", [name, csta["name"], sidp, lat, lng, tz, state, country, units, legal, notes, comments, xfields, refIndex, mint, minlm, maxt, maxlm, sbft, sbet, mindir, maxdir])
    }
  }
end
