/*
 * This file is part of the Vamsas Client version 0.2. 
 * Copyright 2010 by Jim Procter, Iain Milne, Pierre Marguerite, 
 *  Andrew Waterhouse and Dominik Lindner.
 * 
 * Earlier versions have also been incorporated into Jalview version 2.4 
 * since 2008, and TOPALi version 2 since 2007.
 * 
 * The Vamsas Client is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *  
 * The Vamsas Client 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 Lesser General Public License for more details.
 * 
 * You should have received a copy of the GNU Lesser General Public License
 * along with the Vamsas Client.  If not, see <http://www.gnu.org/licenses/>.
 */
package uk.ac.vamsas.test.simpleclient;

import java.io.File;
import java.util.Iterator;
import java.util.Vector;

import uk.ac.vamsas.client.ClientHandle;
import uk.ac.vamsas.client.simpleclient.ClientsFile;
import uk.ac.vamsas.client.simpleclient.FileWatcher;
import uk.ac.vamsas.client.simpleclient.Lock;

public class ClientsFileTest {
  private static CommandProcessor cproc;

  private static Vector commands;
  static {
    cproc = new CommandProcessor();
    ClientsFileTest.commands = new Vector();
    ClientsFileTest.commands.add(new String("add"));
    cproc.addCommand("add", 2, "for the Client's 'Name' and 'Version'");
    ClientsFileTest.commands.add(new String("remove"));
    cproc.addCommand("remove", 3, "for the Client's 'Name', Version and URN");
    ClientsFileTest.commands.add(new String("list"));
    cproc.addCommand("list", 0, "no args needed");
    ClientsFileTest.commands.add(new String("clear"));
    cproc.addCommand("clear", 0, "no args needed");
    ClientsFileTest.commands.add(new String("watch"));
    cproc.addCommand("watch", 0, "no args needed");
    ClientsFileTest.commands.add(new String("monitor"));
    cproc.addCommand("monitor", 2, "for the Client's 'Name' and 'Version'");
  }

  private static void complainArgs(int argl, int argpos, String cmd,
      int argneed, String msg) {
    if (argl - argpos < argneed)
      throw new Error(cmd + " needs " + argneed + " arguments : " + msg);
  }

  public static void main(String[] args) {
    java.io.File cf = new java.io.File(args[0]);
    System.out.println("Connecting to clientFile " + args[0]);
    ClientsFile cfhand;
    try {
      cfhand = new ClientsFile(cf);
    } catch (Exception e) {
      e.printStackTrace(System.err);
      return;
    }
    int argc = 1;
    while (argc < args.length) {
      // vars needed for operations
      ClientHandle ch;
      int com = cproc.getCommand(args, argc);
      argc++;
      switch (com) {
      case 0:
        // Add
        int pos = cfhand.addClient(ch = new ClientHandle(args[argc],
            args[argc + 1]));
        argc += 2;
        if (pos != 0)
          System.out.println("Client added at " + pos + " as urn:"
              + ch.getClientUrn());
        else
          System.out.println("Client was not added.");
        break;
      case 1:
        // remove
        ch = new ClientHandle(args[argc], args[argc + 1]);
        ch.setClientUrn(args[argc + 2]);
        argc += 3;
        cfhand.removeClient(ch, null);
        System.out.println("Client removed (apparently)");
        break;
      case 2:
        // list
        ClientHandle[] chlist = cfhand.retrieveClientList();
        if (chlist != null) {
          for (int chi = 0, che = chlist.length; chi < che; chi++) {
            System.out.println("Client " + chi + " ("
                + chlist[chi].getClientName() + " " + chlist[chi].getVersion()
                + " " + chlist[chi].getClientUrn() + ")");
          }
        } else {
          System.out.println("Client list is empty.");
        }
        break;
      case 3:
        // clear
        // cfhand.get = null;
        // cf.delete();
        try {

          cfhand.clearList();

        } catch (Exception e) {
          System.err.println("Failed on new empty clientfile creation!");
          e.printStackTrace(System.err);
        }
        break;
      case 4:
        // watch
        FileWatcher w = new FileWatcher(cf);
        while (cf.exists()) {
          // get watcher's lock to ensure state change is fixed for retrieval
          Lock chlock = w.getChangedState();
          if (chlock != null) {
            ClientHandle[] cl = cfhand.retrieveClientList(chlock);
            System.out.println("-- Watching " + cf.getName());
            // while (w.hasChanged())
            // ;
            if (cl != null) {
              for (int chi = 0, che = cl.length; chi < che; chi++) {
                System.out.println("Client " + chi + " ("
                    + cl[chi].getClientName() + " " + cl[chi].getVersion()
                    + " " + cl[chi].getClientUrn() + ")");
              }
            } else {
              System.out.println("Client list is empty.");
            }
          }

        }
        break;
      case 5:
        // monitor
        int clpos = cfhand.addClient(ch = new ClientHandle(args[argc],
            args[argc + 1]));
        argc += 2;
        if (clpos != 0)
          System.out.println("Monitor Client added at " + clpos + " as urn:"
              + ch.getClientUrn());
        else {
          System.err.println("Monitor Client was not added.");
          break;
        }
        FileWatcher mon = new FileWatcher(cf);
        while (cf.exists()) {
          // get watcher's lock to ensure state change is fixed for retrieval
          Lock chlock = mon.getChangedState();
          if (chlock != null) {
            ClientHandle[] cl = cfhand.retrieveClientList(chlock);
            System.out.println("-- Monitor " + cf.getName());
            // while (w.hasChanged())
            // ;
            int newpos = -1;
            if (cl != null) {
              for (int chi = 0, che = cl.length; chi < che; chi++) {
                if (ch.equals(cl[chi]))
                  newpos = chi + 1;
              }
            }
            if (newpos == -1) {
              // add self again to cleared list.
              newpos = cfhand.addClient(ch);
              mon.setState();
              if (newpos == 0) {
                System.err
                    .println("Monitor client could not be re-added to list.");
                break;
              }
            }
            if (newpos != clpos) {
              System.out.println("Monitor client moved from " + clpos + " to "
                  + newpos);
              clpos = newpos;
            }
          }
        }
        break;
      default:
        if (com == -1) {
          System.err
              .println("Unknown command : " + args[argc++] + "*Ignored!*");
        } else
          System.err.println("Command " + args[argc++]
              + " *Ignored!* - its not implemented.");
      }

      for (int j = 0; j < 900000; j++) {
        Integer i = Integer.getInteger("1");
        Integer q = i;
      }
    }

  }

  /*
   * Iterator coms = commands.iterator(); int com=-1; while ((coms!=null) &&
   * coms.hasNext()) { com++; if (args[argc].toLowerCase().equals((String)
   * coms.next())) { System.out.println("Doing "+args[argc]); ClientHandle ch;
   * argc++; switch (com) { case 0: // Add
   * ClientsFileTest.complainArgs(args.length, argc, "add", 2,
   * "for the Client's 'Name' and 'Version'"); int pos = cfhand.addClient(ch=new
   * ClientHandle(args[argc],args[argc+1])); argc+=2; if (pos!=0)
   * System.out.println("Client added at "+pos+" as urn:"+ch.getClientUrn());
   * else System.out.println("Client was not added."); break; case 1: // remove
   * ClientsFileTest.complainArgs(args.length, argc, "remove", 3,
   * "for the Client's 'Name', Version and URN"); ch=new
   * ClientHandle(args[argc], args[argc+1]); ch.setClientUrn(args[argc+2]);
   * argc+=3; cfhand.removeClient(ch, null);
   * System.out.println("Client removed (apparently)"); break; case 2: // list
   * ClientHandle[] chlist = cfhand.retrieveClientList(); if (chlist!=null) {
   * for (int chi=0,che=chlist.length; chi<che; chi++) {
   * System.out.println("Client "
   * +chi+" ("+chlist[chi].getClientName()+" "+chlist
   * [chi].getVersion()+" "+chlist[chi].getClientUrn()+")"); } } else {
   * System.out.println("Client list is empty."); } break; case 3: // clear
   * cfhand = null; cf.delete(); try { cf.createNewFile(); cfhand = new
   * ClientsFile(cf); } catch (Exception e) {
   * System.err.println("Failed on new empty clientfile creation!");
   * e.printStackTrace(System.err); } break; case 4: // watch FileWatcher w=new
   * FileWatcher(cf); while (cf.exists()) { // get watcher's lock to ensure
   * state change is fixed for retrieval Lock chlock=w.getChangedState(); if
   * (chlock!=null) { ClientHandle[] cl = cfhand.retrieveClientList(chlock);
   * System.out.println("-- Watching "+cf.getName()); //while (w.hasChanged())
   * // ; if (cl!=null) { for (int chi=0,che=cl.length; chi<che; chi++) {
   * System.
   * out.println("Client "+chi+" ("+cl[chi].getClientName()+" "+cl[chi].getVersion
   * ()+" "+cl[chi].getClientUrn()+")"); } } else {
   * System.out.println("Client list is empty."); } }
   * 
   * } break; case 5: // monitor ClientsFileTest.complainArgs(args.length, argc,
   * "monitor", 2, "for the Client's 'Name' and 'Version'"); int clpos =
   * cfhand.addClient(ch=new ClientHandle(args[argc],args[argc+1])); argc+=2; if
   * (clpos!=0)
   * System.out.println("Monitor Client added at "+clpos+" as urn:"+ch
   * .getClientUrn()); else {
   * System.err.println("Monitor Client was not added."); break; } FileWatcher
   * mon=new FileWatcher(cf); while (cf.exists()) { // get watcher's lock to
   * ensure state change is fixed for retrieval Lock
   * chlock=mon.getChangedState(); if (chlock!=null) { ClientHandle[] cl =
   * cfhand.retrieveClientList(chlock);
   * System.out.println("-- Monitor "+cf.getName()); //while (w.hasChanged()) //
   * ; int newpos=-1; if (cl!=null) { for (int chi=0,che=cl.length; chi<che;
   * chi++) { if (ch.equals(cl[chi])) newpos=chi+1; } } if (newpos==-1) { // add
   * self again to cleared list. newpos=cfhand.addClient(ch); mon.setState(); if
   * (newpos==0) {
   * System.err.println("Monitor client could not be re-added to list."); break;
   * } } if (newpos!=clpos) {
   * System.out.println("Monitor client moved from "+clpos+" to "+newpos);
   * clpos=newpos; } } }
   * 
   * } coms = null; } }
   */

}
