package net;

/**
 * Class:   GetTimeConsole
 * @author:     James Linn, D. Lyon
 *
 * Date:    1/20/2001
 * Time:    11:14:12 PM
 */

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.Socket;
import java.net.UnknownHostException;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.GregorianCalendar;
import java.util.StringTokenizer;
import java.util.TimeZone;

/** Get the time from the NIST atomic clock
 *
 * @author Douglas Lyon
 * @version 1.0
 */
public class AtomicClock {
  /** get a reader that reads the time
   *
   * @since 9/4/02
   * @exception UnknownHostException It cannot connect to NIST
   * @exception IOException When we cannot set the time
   * @return the buffered reader
   */
  public static BufferedReader getReader()
      throws UnknownHostException,
      IOException {
    Socket s = new Socket(
        "time-A.timefreq.bldrdoc.gov", 13);
    return new BufferedReader(
        new InputStreamReader(
            s.getInputStream()));
  }

  /** set the system clock
   *
   * @since 9/4/02
   * @param c A calender instance that is used to set the time
   * @exception IOException When we cannot set the time
   */
  public static void setSystemTime(GregorianCalendar c)
      throws IOException {
    // Now set the computer to this time:
    Runtime rt = Runtime.getRuntime();
    StringTokenizer st = new StringTokenizer(
        c.getTime().toString(), " ");
    for (int i = 0; i < 3; i++)
      st.nextToken();

    String[] execArgArray = new String[2];
    execArgArray[0] = "c:\\SW409\\settime.bat";
    execArgArray[1] = st.nextToken();
    rt.exec(execArgArray);
  }

  /** Convert the NIST time to an instance of a calendar
   *
   * @param line The raw string returned from NIST
   * @return a calendar instance
   */
  public static GregorianCalendar parseDate(String line) {
    StringTokenizer sTok =
        new StringTokenizer(line, " ");
    sTok.nextToken();
    // Get # at the beginning,
    // whatever it represents
    String sDate = sTok.nextToken();
    String sTime = sTok.nextToken();
    SimpleDateFormat df =
        new SimpleDateFormat("yy-MM-dd hh:mm:ss");
    df.setTimeZone(TimeZone.getTimeZone("GMT"));
    GregorianCalendar cal = new GregorianCalendar();
    cal.setTimeZone(TimeZone.getTimeZone("GMT"));
    try {
      cal.setTime(df.parse(sDate + " " + sTime));
    } catch (ParseException e) {
      System.out.println(e.getMessage());
    }
    System.out.println(cal.getTime());
    return cal;
  }

  /** @param s
   * @exception IOException
   */
  public static void processLine(String s)
      throws IOException {
    if (s.length() == 0) return;
    System.out.println(s);
    setSystemTime(parseDate(s));
    sleep();
  }

  /** Reads in the time to internal state variables
   *
   * @exception UnknownHostException
   * @exception IOException
   */
  public static void getTime()
      throws UnknownHostException, IOException {
    BufferedReader br = getReader();
    String s = null;
    while ((s = br.readLine()) != null)
      processLine(s);
  }

  public static void sleep() {
    try {
      Thread.sleep(5000);
      // Gives time to read msg
    } catch (InterruptedException ie) {
    }
  }

  /** A unit test
   *
   * @since 1.0
   * @param args not used
   */
  public static void main(String[] args) {
    try {
      AtomicClock.getTime();
    } catch (Exception e) {
      e.printStackTrace();
    }
  }
}