#!/usr/bin/env coffee

{spawn} = require "child_process"

fs = require "fs"

name = process.argv[2] || "en_US"
output = process.argv[3] || "locale"
bash = spawn "bash"
bash.stdin.write """
export TZ=UTC
locale=#{name}
days=()
for i in {1..7}
do
    days+=($(LANG=$locale.UTF-8 date -d '2006-01-0'$i +'%a'))
done
echo ${days[*]}

days=()
for i in {1..7}
do
    days+=($(LANG=$locale.UTF-8 date -d '2006-01-0'$i +'%A'))
done
echo ${days[*]}

months=()
for i in {1..12}
do
    number=$(printf '%02d' $i)
    months+=($(LANG=$locale.UTF-8 date -d '2000-'$number-'01' +'%b'))
done
echo ${months[*]}

months=()
for i in {1..12}
do
    number=$(printf '%02d' $i)
    months+=($(LANG=$locale.UTF-8 date -d '2000-'$number-'01' +'%B'))
done
echo ${months[*]}

LANG=$locale.UTF-8 date -d '2000-09-03 08:05:04' +'%p'
LANG=$locale.UTF-8 date -d '2000-09-03 23:05:04' +'%p'
LANG=$locale.UTF-8 date -d '2000-09-03 08:05:04' +'%P'
LANG=$locale.UTF-8 date -d '2000-09-03 23:05:04' +'%P'
LANG=$locale.UTF-8 date -d 2000-09-03 +'%x'
LANG=$locale.UTF-8 date -d 2000-09-03 +'%x'
LANG=$locale.UTF-8 date -d '2000-09-03 08:05:04' +'%X'
LANG=$locale.UTF-8 date -d '2000-09-03 23:05:04' +'%X'
LANG=$locale.UTF-8 date -d '2000-09-03 08:05:04' +'%c'
LANG=$locale.UTF-8 date -d '2000-09-03 23:05:04' +'%c'
"""
bash.stdin.end()
stdout = []
bash.stdout.on "data", (chunk) ->
  stdout.push chunk.toString "utf8"
bash.on "exit", (code) ->
  if code
    console.log { code }
    process.exit 1
  else
    stdout = stdout.join("").split(/\n/)
    if output is "locale"
      for line in stdout
        process.stdout.write "// #{line}\n"
      locale = { name, day: {}, month: {}, meridiem: [ "", "" ] }
      locale.day.abbrev = stdout.shift().split(/\s+/)
      locale.day.full = stdout.shift().split(/\s+/)
      locale.month.abbrev = stdout.shift().split(/\s+/)
      locale.month.full = stdout.shift().split(/\s+/)
      [ am, pm ] = stdout.splice(0, 2)
      if am and pm
        locale.meridiem[0] = am
        locale.meridiem[1] = pm
      [ am, pm ] = stdout.splice(0, 2)
      if am and pm
        if locale.meridiem[0].toLowerCase() isnt am
          throw new Error('nope')
        if locale.meridiem[1].toLowerCase() isnt pm
          throw new Error('nope')
      [ am, pm ] = stdout.splice(0, 2)
      locale.date = createPattern locale, am, pm
      [ am, pm ] = stdout.splice(0, 2)
      locale.time24 = createPattern locale, am, pm
      [ am, pm ] = stdout.splice(0, 2)
      locale.dateTime = createPattern locale, am, pm
      process.stdout.write "module.exports = "
      process.stdout.write JSON.stringify locale, null, 2
      process.stdout.write ";\n"
    else
      shortDays = stdout.shift().split(/\s+/)
      days = stdout.shift().split(/\s+/)
      shortMonths = stdout.shift().split(/\s+/)
      months = stdout.shift().split(/\s+/)
      [ AM, PM, am, pm ] = stdout.splice(0, 4)
      [ dateFormat ] = stdout.splice(0, 2)
      [ morningTimeFormat, eveningTimeFormat ] = stdout.splice(0, 2)
      [ morningDateTimeFormat, eveningDateTimeFormat ] = stdout.splice(0, 2)
      try
        fs.mkdirSync "t/locale/#{name}", 0o755
      catch e
        throw e unless e.code is "EEXIST"
      fs.writeFileSync "t/locale/#{name}/days.t", """
      #!/usr/bin/env node
      require("../../proof")(14, function (tz, equal) {
        var tz = tz(require("timezone/#{name}"));
        // #{name} abbreviated days of week
        equal(tz("2006-01-01", "%a", "#{name}"), "#{shortDays[0]}", "Sun");
        equal(tz("2006-01-02", "%a", "#{name}"), "#{shortDays[1]}", "Mon");
        equal(tz("2006-01-03", "%a", "#{name}"), "#{shortDays[2]}", "Tue");
        equal(tz("2006-01-04", "%a", "#{name}"), "#{shortDays[3]}", "Wed");
        equal(tz("2006-01-05", "%a", "#{name}"), "#{shortDays[4]}", "Thu");
        equal(tz("2006-01-06", "%a", "#{name}"), "#{shortDays[5]}", "Fri");
        equal(tz("2006-01-07", "%a", "#{name}"), "#{shortDays[6]}", "Sat");

        // #{name} days of week
        equal(tz("2006-01-01", "%A", "#{name}"), "#{days[0]}", "Sunday");
        equal(tz("2006-01-02", "%A", "#{name}"), "#{days[1]}", "Monday");
        equal(tz("2006-01-03", "%A", "#{name}"), "#{days[2]}", "Tuesday");
        equal(tz("2006-01-04", "%A", "#{name}"), "#{days[3]}", "Wednesday");
        equal(tz("2006-01-05", "%A", "#{name}"), "#{days[4]}", "Thursday");
        equal(tz("2006-01-06", "%A", "#{name}"), "#{days[5]}", "Friday");
        equal(tz("2006-01-07", "%A", "#{name}"), "#{days[6]}", "Saturday");
      });

      """, "utf8"
      fs.chmodSync "t/locale/#{name}/days.t", 0o755

      fs.writeFileSync "t/locale/#{name}/months.t", """
      #!/usr/bin/env node
      require("../../proof")(24, function (tz, equal) {
        var tz = tz(require("timezone/#{name}"));
        //#{name} abbreviated months
        equal(tz("2000-01-01", "%b", "#{name}"), "#{shortMonths[0]}", "Jan");
        equal(tz("2000-02-01", "%b", "#{name}"), "#{shortMonths[1]}", "Feb");
        equal(tz("2000-03-01", "%b", "#{name}"), "#{shortMonths[2]}", "Mar");
        equal(tz("2000-04-01", "%b", "#{name}"), "#{shortMonths[3]}", "Apr");
        equal(tz("2000-05-01", "%b", "#{name}"), "#{shortMonths[4]}", "May");
        equal(tz("2000-06-01", "%b", "#{name}"), "#{shortMonths[5]}", "Jun");
        equal(tz("2000-07-01", "%b", "#{name}"), "#{shortMonths[6]}", "Jul");
        equal(tz("2000-08-01", "%b", "#{name}"), "#{shortMonths[7]}", "Aug");
        equal(tz("2000-09-01", "%b", "#{name}"), "#{shortMonths[8]}", "Sep");
        equal(tz("2000-10-01", "%b", "#{name}"), "#{shortMonths[9]}", "Oct");
        equal(tz("2000-11-01", "%b", "#{name}"), "#{shortMonths[10]}", "Nov");
        equal(tz("2000-12-01", "%b", "#{name}"), "#{shortMonths[11]}", "Dec");

        // #{name} months
        equal(tz("2000-01-01", "%B", "#{name}"), "#{months[0]}", "January");
        equal(tz("2000-02-01", "%B", "#{name}"), "#{months[1]}", "February");
        equal(tz("2000-03-01", "%B", "#{name}"), "#{months[2]}", "March");
        equal(tz("2000-04-01", "%B", "#{name}"), "#{months[3]}", "April");
        equal(tz("2000-05-01", "%B", "#{name}"), "#{months[4]}", "May");
        equal(tz("2000-06-01", "%B", "#{name}"), "#{months[5]}", "June");
        equal(tz("2000-07-01", "%B", "#{name}"), "#{months[6]}", "July");
        equal(tz("2000-08-01", "%B", "#{name}"), "#{months[7]}", "August");
        equal(tz("2000-09-01", "%B", "#{name}"), "#{months[8]}", "September");
        equal(tz("2000-10-01", "%B", "#{name}"), "#{months[9]}", "October");
        equal(tz("2000-11-01", "%B", "#{name}"), "#{months[10]}", "November");
        equal(tz("2000-12-01", "%B", "#{name}"), "#{months[11]}", "December");
      });

      """, "utf8"
      fs.chmodSync "t/locale/#{name}/months.t", 0o755

      fs.writeFileSync "t/locale/#{name}/formats.t", """
      #!/usr/bin/env node
      require("../../proof")(5, function (tz, equal) {
        var tz = tz(require("timezone/#{name}"));
        // #{name} date representation
        equal(tz("2000-09-03", "%x", "#{name}"), "#{dateFormat}", "date format");

        // #{name} time representation
        equal(tz("2000-09-03 08:05:04", "%X", "#{name}"), "#{morningTimeFormat}", "long time format morning");
        equal(tz("2000-09-03 23:05:04", "%X", "#{name}"), "#{eveningTimeFormat}", "long time format evening");

        // #{name} date time representation
        equal(tz("2000-09-03 08:05:04", "%c", "#{name}"), "#{morningDateTimeFormat}", "long date format morning");
        equal(tz("2000-09-03 23:05:04", "%c", "#{name}"), "#{eveningDateTimeFormat}", "long date format evening");
      });

      """, "utf8"
      fs.chmodSync "t/locale/#{name}/formats.t", 0o755

      if am or AM or pm or PM
        fs.writeFileSync "t/locale/#{name}/meridiem.t", """
        #!/usr/bin/env node
        require("../../proof")(4, function (tz, equal) {
          var tz = tz(require("timezone/#{name}"));
          // #{name} meridiem upper case
          equal(tz("2000-09-03 08:05:04", "%P", "#{name}"), "#{am}", "ante meridiem lower case");
          equal(tz("2000-09-03 23:05:04", "%P", "#{name}"), "#{pm}", "post meridiem lower case");

          // #{name} meridiem lower case
          equal(tz("2000-09-03 08:05:04", "%p", "#{name}"), "#{AM}", "ante meridiem upper case");
          equal(tz("2000-09-03 23:05:04", "%p", "#{name}"), "#{PM}", "post meridiem upper case");
        });

        """, "utf8"
        fs.chmodSync "t/locale/#{name}/meridiem.t", 0o755

count=0
createPattern = (locale, am, pm) ->
  am = am.replace("04", "%S")
  am = am.replace("05", "%M")
  console.error(pm)
  clock = if /11/.test pm then "I" else "H"
  am = am.replace("08", "%#{clock}")
  am = am.replace(/^ 8/, "%_#{clock}")
  am = am.replace("  8", " %_#{clock}")
  am = am.replace(" 8", " %-#{clock}")
  am = am.replace("03", "%d")
  am = am.replace("  3", " %_d")
  am = am.replace(" 3", " %-d")
  am = am.replace("09", "%m")
  am = am.replace("9", "%-m")
  am = am.replace("2000", "%Y")
  am = am.replace("00", "%y")
  am = am.replace("UTC", "%Z")
  am = am.replace(locale.meridiem[0], "%p")
  am = am.replace(locale.meridiem[0].toLowerCase(), "%P")
  am = am.replace(locale.day.abbrev[0], "%a")
  am = am.replace(locale.day.full[0], "%A")
  am = am.replace(locale.month.abbrev[8], "%b")
  am = am.replace(locale.month.full[8], "%B")
  am
