package de.knipp.registryannouncements;

import java.io.FileWriter;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.TimeZone;


public class Ascii
{
  private static final int LEFT_WIDTH = 25;
  private static final int RIGHT_WIDTH = 50;

  StringBuffer sb = new StringBuffer ();


  public Ascii (Announcement a)
  {
    sb.append (beautify ("Registry", 
      a.getRegistryName () + " (" + a.getDomain () + ")"));

    sb.append (beautify ("Registry Message ID", a.getId ()));

    sb.append (beautify ("Announcement type", a.getType ()));

    SimpleDateFormat formatter = new SimpleDateFormat ("yyyy-MM-dd'T'HH:mm:ss.SSSZ");
    SimpleDateFormat displayFormatter = new SimpleDateFormat("E yyyy-MM-dd HH:mm:ss z");
    String from = a.getDateFrom ().replaceFirst ("Z", "+0000");
    String to = a.getDateTo ().replaceFirst ("Z", "+0000");
    try
    {
      Date dateFrom = formatter.parse (from);
      String timezone = "America/Los_Angeles";
      TimeZone tz = TimeZone.getTimeZone (timezone);
      displayFormatter.setTimeZone (tz);
      sb.append (beautify ("From", displayFormatter.format (dateFrom) + " (" + timezone + ")"));

      timezone = "America/New_York";
      tz = TimeZone.getTimeZone (timezone);
      displayFormatter.setTimeZone (tz);
      sb.append (beautify (displayFormatter.format (dateFrom) + " (" + timezone + ")"));

      timezone = "Europe/Berlin";
      tz = TimeZone.getTimeZone (timezone);
      displayFormatter.setTimeZone (tz);
      sb.append (beautify (displayFormatter.format (dateFrom) + " (" + timezone + ")"));

      timezone = "Asia/Tokyo";
      tz = TimeZone.getTimeZone (timezone);
      displayFormatter.setTimeZone (tz);
      sb.append (beautify (displayFormatter.format (dateFrom) + " (" + timezone + ")"));

      Date dateTo = formatter.parse (to);
      timezone = "America/Los_Angeles";
      tz = TimeZone.getTimeZone (timezone);
      displayFormatter.setTimeZone (tz);
      sb.append (beautify ("To", displayFormatter.format (dateTo) + " (" + timezone + ")"));

      timezone = "America/New_York";
      tz = TimeZone.getTimeZone (timezone);
      displayFormatter.setTimeZone (tz);
      sb.append (beautify (displayFormatter.format (dateTo) + " (" + timezone + ")"));

      timezone = "Europe/Berlin";
      tz = TimeZone.getTimeZone (timezone);
      displayFormatter.setTimeZone (tz);
      sb.append (beautify (displayFormatter.format (dateTo) + " (" + timezone + ")"));

      timezone = "Asia/Tokyo";
      tz = TimeZone.getTimeZone (timezone);
      displayFormatter.setTimeZone (tz);
      sb.append (beautify (displayFormatter.format (dateTo) + " (" + timezone + ")"));
    }
    catch (Exception ex)
    {
      // should not happen due schema definition
      System.err.println ("date formatter: " + ex);
    }

    String affected =
      (a.isAffectedProdSrs () ? "srs " : "") +
      (a.isAffectedProdWhois () ? "whois " : "") +
      (a.isAffectedProdAdminWebsite () ? "admin-website " : "") +
      (a.isAffectedProdDns () ? "dns " : "") +
      (a.isAffectedProdOther () ? "other " : "");
    if (affected.length () > 0)
      sb.append (beautify ("Affected prod systems", affected));

    affected =
      (a.isAffectedOteSrs () ? "srs " : "") +
      (a.isAffectedOteWhois () ? "whois " : "") +
      (a.isAffectedOteAdminWebsite () ? "admin-website " : "") +
      (a.isAffectedOteDns () ? "dns " : "") +
      (a.isAffectedOteOther () ? "other " : "");
    if (affected.length () > 0)
      sb.append (beautify ("Affected OTE systems", affected));

    for (Description d: a.getDescriptions ())
      sb.append (beautify ("Message", d.getMessage ()));
  }


  public String toString () {return sb.toString ();}

  public void toFile (String fileName)
  {
    FileWriter fw;
    try 
    {
      fw = new FileWriter (fileName);
      fw.write (sb.toString ());
      fw.close ();
    }
    catch (IOException e)
    {
      System.err.println ("fatal: could not write to " + fileName);
      System.err.println ("Exception: " + e);
      System.exit (-1);
    }
  }


  private StringBuffer beautify (String left, String right)
  {
    // dotted key
    StringBuffer res = new StringBuffer (left);
    res.append (" ");
    int l = left.length ();
    for (int i = left.length (); i <= LEFT_WIDTH - 3; i++) res.append (".");
    res.append (":");

    return beautify (res, right);
  }


  private StringBuffer beautify (String right)
  {
    // no key, only blanks
    StringBuffer res = new StringBuffer ();
    for (int i = 1; i <= LEFT_WIDTH; i++) res.append (" ");

    return beautify (res, right);
  }


  private StringBuffer beautify (StringBuffer left, String right)
  {
    StringBuffer res = new StringBuffer (left);

    // left tab for additional lines
    StringBuffer leftMargin = new StringBuffer ();
    for (int i = 1; i <= LEFT_WIDTH; i++) leftMargin.append (" ");

    // value(s)
    String[] tokens = right.split (" ");
    int lineLength = LEFT_WIDTH;
    boolean firstToken = true;
    for (int i = 0; i < tokens.length; i++)
    {
      String token = tokens[i];
      int tokenLength = token.length ();
      if (!firstToken && lineLength + tokenLength > LEFT_WIDTH + RIGHT_WIDTH)
      {
        res.append ("\n");
        res.append (leftMargin);
        lineLength = LEFT_WIDTH + tokenLength;
      }
      else
      {
        lineLength += tokenLength + 1;
      }
      res.append (" ");
      res.append (token);
      firstToken = false;
    }
    res.append ("\n");

    return new StringBuffer (res);
  }
}
