/*
 * The Apache Software License, Version 1.1
 *
 * Copyright (c) 2000 The Apache Software Foundation.  All rights
 * reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 *
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in
 *    the documentation and/or other materials provided with the
 *    distribution.
 *
 * 3. The end-user documentation included with the redistribution, if
 *    any, must include the following acknowlegement:
 *       "This product includes software developed by the
 *        Apache Software Foundation (http://www.apache.org/)."
 *    Alternately, this acknowlegement may appear in the software itself,
 *    if and wherever such third-party acknowlegements normally appear.
 *
 * 4. The names "The Jakarta Project", "Ant", and "Apache Software
 *    Foundation" must not be used to endorse or promote products derived
 *    from this software without prior written permission. For written
 *    permission, please contact apache@apache.org.
 *
 * 5. Products derived from this software may not be called "Apache"
 *    nor may "Apache" appear in their names without prior written
 *    permission of the Apache Group.
 *
 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 * ====================================================================
 *
 * This software consists of voluntary contributions made by many
 * individuals on behalf of the Apache Software Foundation.  For more
 * information on the Apache Software Foundation, please see
 * <http://www.apache.org/>.
 */

package org.apache.tools.ant.taskdefs.optional.net;

import org.apache.tools.ant.BuildException;
import org.apache.tools.ant.Task;
import org.apache.tools.ant.Project;
import org.apache.tools.ant.DirectoryScanner;
import org.apache.tools.ant.taskdefs.MatchingTask;
import com.oroinc.net.telnet.*;
import org.apache.tools.ant.BuildException;
import java.io.*;
import java.lang.*;
import java.util.*;

/**
 * Class to provide automated telnet protocol support for the Ant build tool
 *
 * @author Scott Carlson<a href="mailto:ScottCarlson@email.com">ScottCarlson@email.com</a>
 * @version $Revision$
 */

public class TelnetTask extends Task {
    /**
     *  The userid to login with, if automated login is used
     */
    private String userid  = null;

    /**
     *  The password to login with, if automated login is used
     */
    private String password= null;

    /**
     *  The server to connect to. 
     */
    private String server  = null;

    /**
     *  The tcp port to connect to. 
     */
    private int port = 23;

    /**
     *  The Object which handles the telnet session.
     */
    private AntTelnetClient telnet = null;

    /**
     *  The list of read/write commands for this session
     */
    private Vector telnetTasks = new Vector();

    /** 
     *  If true, adds a CR to beginning of login script
     */
    private boolean addCarriageReturn = false;

    /**
     *  Default time allowed for waiting for a valid response
     *  for all child reads.  A value of 0 means no limit.
     */
    private Integer defaultTimeout = null;

    /** 
     *  Verify that all parameters are included. 
     *  Connect and possibly login
     *  Iterate through the list of Reads and writes 
     */
    public void execute() throws BuildException 
    {
       /**  A server name is required to continue */
       if (server== null)
           throw new BuildException("No Server Specified");
       /**  A userid and password must appear together 
        *   if they appear.  They are not required.
        */
       if (userid == null && password != null)
           throw new BuildException("No Userid Specified");
       if (password == null && userid != null)
           throw new BuildException("No Password Specified");

       /**  Create the telnet client object */
       telnet = new AntTelnetClient();
       try {
           telnet.connect(server, port);
       } catch(IOException e) {
           throw new BuildException("Can't connect to "+server);
       }
       /**  Login if userid and password were specified */
       if (userid != null && password != null)
          login();
       /**  Process each sub command */
       Enumeration tasksToRun = telnetTasks.elements();
       while (tasksToRun!=null && tasksToRun.hasMoreElements())
       {
           TelnetSubTask task = (TelnetSubTask) tasksToRun.nextElement();
           if (task instanceof TelnetRead && defaultTimeout != null)
               ((TelnetRead)task).setDefaultTimeout(defaultTimeout);
           task.execute(telnet);
       }
    }

    /**  
     *  Process a 'typical' login.  If it differs, use the read 
     *  and write tasks explicitely
     */
    private void login()
    {
       if (addCarriageReturn)
          telnet.sendString("\n", true);
       telnet.waitForString("ogin:");
       telnet.sendString(userid, true);
       telnet.waitForString("assword:");
       telnet.sendString(password, false);
    }

    /**
     *  Set the userid attribute 
     */
    public void setUserid(String u) { this.userid = u; }

    /**
     *  Set the password attribute 
     */
    public void setPassword(String p) { this.password = p; }

    /**
     *  Set the server address attribute 
     */
    public void setServer(String m) { this.server = m; }

    /**
     *  Set the tcp port to connect to attribute 
     */
    public void setPort(int p) { this.port = p; }

    /**
     *  Set the tcp port to connect to attribute 
     */
    public void setInitialCR(boolean b)
    {
       this.addCarriageReturn = b;
    }

    /**
     *  Change the default timeout to wait for 
     *  valid responses
     */
    public void setTimeout(Integer i)
    {
       this.defaultTimeout = i;
    }

    /**
     *  A subTask <read> tag was found.  Create the object, 
     *  Save it in our list, and return it.
     */
   
    public TelnetSubTask createRead()
    {
        TelnetSubTask task = (TelnetSubTask)new TelnetRead();
        telnetTasks.addElement(task);
        return task;
    }

    /**
     *  A subTask <write> tag was found.  Create the object, 
     *  Save it in our list, and return it.
     */
    public TelnetSubTask createWrite()
    {
        TelnetSubTask task = (TelnetSubTask)new TelnetWrite();
        telnetTasks.addElement(task);
        return task;
    }

    /**  
     *  This class is the parent of the Read and Write tasks.
     *  It handles the common attributes for both.
     */
    public class TelnetSubTask
    {
        protected String taskString= "";
        public void execute(AntTelnetClient telnet) 
                throws BuildException
        {
            throw new BuildException("Shouldn't be able instantiate a SubTask directly");
        }
        public void addText(String s) { setString(s);}
        public void setString(String s)
        {
           taskString += s; 
        }
    }
    /**
     *  This class sends text to the connected server 
     */
    public class TelnetWrite extends TelnetSubTask
    {
        private boolean echoString = true;
        public void execute(AntTelnetClient telnet) 
               throws BuildException
        {
           telnet.sendString(taskString, echoString);
        }
        
        public void setEcho(boolean b)
        {
           echoString = b;
        }
    }
    /**
     *  This class reads the output from the connected server
     *  until the required string is found. 
     */
    public class TelnetRead extends TelnetSubTask
    {
        private Integer timeout = null;
        public void execute(AntTelnetClient telnet) 
               throws BuildException
        {
            telnet.waitForString(taskString, timeout);
        }
        /**
         *  Override any default timeouts
         */
        public void setTimeout(Integer i)
        {
           this.timeout = i;
        }
        /**
         *  Sets the default timeout if none has been set already
         */
        public void setDefaultTimeout(Integer defaultTimeout)
        {
           if (timeout == null)
              timeout = defaultTimeout;
    }
    }
    /**
     *  This class handles the abstraction of the telnet protocol.
     *  Currently it is a wrapper around <a href="www.oroinc.com">ORO</a>'s 
     *  NetComponents
     */
    public class AntTelnetClient extends TelnetClient
    {
      /**
       * Read from the telnet session until the string we are 
       * waiting for is found 
       * @parm s The string to wait on 
       */
      public void waitForString(String s)
      {
           waitForString(s, null);
      }

      /**
       * Read from the telnet session until the string we are 
       * waiting for is found or the timeout has been reached
       * @parm s The string to wait on 
       * @parm timeout The maximum number of seconds to wait
       */
      public void waitForString(String s, Integer timeout)
      {
        InputStream is =this.getInputStream();
        try {
          StringBuffer sb = new StringBuffer();
          if (timeout == null || timeout.intValue() == 0)
          {
              while (sb.toString().indexOf(s) == -1)
                  {
                      sb.append((char) is.read());
                  }
          }
          else
          {
              Calendar endTime = Calendar.getInstance(); 
              endTime.add(Calendar.SECOND,timeout.intValue());
              while ( sb.toString().indexOf(s) == -1)
              {
                  while (Calendar.getInstance().before(endTime) &&
                         is.available() == 0) {
                      Thread.sleep(250);
                  }
                  if (is.available() == 0)
                      throw new BuildException("Response Timed-Out", getLocation());
                  sb.append((char) is.read());
              }
          }
          log(sb.toString(), Project.MSG_INFO);
        } catch (BuildException be)
        { 
            throw be;
        } catch (Exception e)
        { 
            throw new BuildException(e, getLocation());
        }
      }

    
      /**
       * Write this string to the telnet session.
       * @parm echoString  Logs string sent
       */
      public void sendString(String s, boolean echoString)
      {
        OutputStream os =this.getOutputStream();
        try {
          os.write((s + "\n").getBytes());
          if (echoString)
              log(s, Project.MSG_INFO);
          os.flush();
        } catch (Exception e)
        { 
          throw new BuildException(e, getLocation());
        }
      }
    }
}
