/*
** Module   : TerminalTestExecutor.java
** Abstract : An executor of terminal tests. 
**
** Copyright (c) 2021-2023, Golden Code Development Corporation.
**
** -#- -I- --Date-- ---------------------------------------Description----------------------------------------
** 001 CA  20210827 Created initial version.
** 002 RFB 20230111 Added finer logging which helps with debug (plus review).
** 003 TJD 20230119 Added log level trace
*/

/*
** This program is free software: you can redistribute it and/or modify
** it under the terms of the GNU Affero General Public License as
** published by the Free Software Foundation, either version 3 of the
** License, or (at your option) any later version.
**
** This program 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 Affero General Public License for more details.
**
** You should have received a copy of the GNU Affero General Public License
** along with this program.  If not, see <http://www.gnu.org/licenses/>.
*/

package com.goldencode.harness;

import java.io.*;

import com.goldencode.harness.terminal.*;
import com.goldencode.harness.test.*;
import com.goldencode.harness.transport.*;
import com.goldencode.util.*;

/**
 * The executor for terminal tests.
 */
public class TerminalTestExecutor
extends TestExecutor
{
   /** Low-level communications transport. */ 
   private Connection session = null;
   
   /** The terminal emulator session to the target back-end. */
   private Terminal term = null;
   
   
   /**
    * Construct an instance of a worker thread and establish the connection
    * to the back-end. This includes the creation of the terminal emulator
    * instance which is used for test interaction.
    *
    * @param    cfg
    *           Communications session and terminal emulation configuration       *
    *           for properly contacting the target system.
    * @param    rc
    *           Object in which to store the details of non-testing failures.
    */
   public TerminalTestExecutor(TerminalSessionSettings cfg, FailureNotification rc)
   {
      // connect the session
      session = TransportManager.connect(cfg, rc);
      
      if (session == null)
      {
         // failure details are already in the rc
         return;
      }
      
      OutputStream os = session.getOutputStream(rc);
      InputStream  is = session.getInputStream(rc);
      
      if (os == null || is == null)
      {
         // failure details are already in the rc
         return;
      }
      if (LogHelper.isFinestLoggable())
      {
         LogHelper.finest("outputstream/inputstream before Terminal os=" + os + " is=" + is);
      }
      term = new Terminal(new DataSource(is, os), cfg);
      if (LogHelper.isFinestLoggable())
      {
         LogHelper.finest("terminal created term=" + term);
      }
   }
   
   /**
    * Execute the specified test.
    * 
    * @param    test
    *           The test to execute.
    */
   @Override
   public void execute(Testable test)
   {
      ((TerminalTestable) test).execute(term);
   }
   
   /**
    * Check the pre-condition of this test.
    * 
    * @return   <code>true</code> if the {@link #session} is established.
    */
   @Override
   public boolean pre()
   {
      return session != null;
   }

   /**
    * Post-processing of this test (disconnect the {@link #session}).
    */
   @Override
   public void post()
   {
      if (session != null)
         session.disconnect();
   }
}
