/*
 * 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.client.simpleclient;

import java.io.File;
import java.io.IOException;
import java.util.ArrayList;

import uk.ac.vamsas.client.SessionHandle;


/**
 * Class to deal with sessions
 * 
 * retrieves list of available sessions
 * 
 * adds an active session
 * 
 * removes a close session (the last client has been closed)
 * 
 * 
 */
public class SimpleSessionManager {
  private SessionsFile sessionFile = null;

  protected SimpleSessionManager(File sessionsFile) throws IOException {
    this.initManagerObjects(sessionsFile);
  }

  /**
   * construct SessionFile objects and watchers for each
   */
  private void initManagerObjects(File sessionsFile) throws IOException {
    if (this.sessionFile != null)
      throw new IOException(
          "initFactoryObjects called for initialised ClientFactory object.");
    this.sessionFile = new SessionsFile(sessionsFile);
  }

  /**
   * make a new watcher object for the sessionsFile
   * 
   * @return new SessionsFile watcher instance
   */
  public FileWatcher getSessionsWatcher() {
    return new FileWatcher(this.getSessionFile().sessionFile);
  }

  /**
   * @see uk.ac.vamsas.client.IClientFactory#getCurrentSessions()
   */
  public String[] getCurrentSessions() {
    String[] sessions = null;
    if (this.sessionFile != null) {
      SimpleSessionHandle[] sessionHandles = this.sessionFile.retrieveSessionsList();
      if (sessionHandles != null) {
        sessions = new String[sessionHandles.length];
        for (int i = sessionHandles.length - 1; i > -1; i--) {
          SimpleSessionHandle sessionHandle = sessionHandles[i];
          sessions[i] = sessionHandle.getSessionUrn();
        }
      }
    }
    return sessions;
  }
  /**
   * recover session(s) corresponding to SessionUrn
   * @param urn
   * @return null, or one or more SimpleSessionHandle objects with the given sessionUrn
   */
  public SimpleSessionHandle[] getSessionFor(SessionUrn urn) {
    ArrayList sessions=new ArrayList();
    if (sessionFile != null) {
      SessionHandle pattern = new SessionHandle(urn.getSessionUrn());
      SimpleSessionHandle[] sessionHandles = sessionFile.retrieveSessionsList();
      if (sessionHandles != null) {
        for (int i = sessionHandles.length - 1; i > -1; i--) {
          SimpleSessionHandle sessionHandle = sessionHandles[i];
          if (sessionHandle.equals(pattern))
          {
            sessions.add(sessionHandle);
          }
        }
      }
    }
    if (sessions.size()>0)
    {
      SimpleSessionHandle[] sh = new SimpleSessionHandle[sessions.size()];
      sessions.toArray(sh);
      return sh;
    }
    return null;
  }

  /**
   * adds SessionHandle me to the sessionList
   * 
   * @param newSession
   *          session to add to the session list
   * @return session index in list or 0 if lock was invalid or addSession
   *         operation failed.
   */
  public int addSession(SimpleSessionHandle newSession) {
    return this.sessionFile.addSession(newSession, false, this
        .getSessionsWatcher().getChangedState());
  }

  /**
   * @return the sessionFile
   */
  private SessionsFile getSessionFile() {
    return this.sessionFile;
  }

  /**
   * Removes a session from the list of currently active session
   * 
   * @param session
   *          SessionHandle of the session to remove
   */
  protected void removeSession(SessionHandle session) {
    getSessionFile().removeSession(session,
        this.getSessionsWatcher().getChangedState());
  }
}
