/* 9P Protocol JAVA
 * P9P/server9P.java
 * Autor: Jaime Garzon (2006) jgarzon@gmail.com
 *
 * Esta clase implementa un servidor 9P. EL constructor es:
 * server9P (int maxcon, int maxfid, int p, boolean show, pfile f)
 *
 * El metodo process() ejecuta el servidor.
 * El metodo printMsg() escribre por salida estandar la cadena "s"
*/


package P9P;

import java.io.*;

import PFS.*;
import P9P.msg.*;
import P9P.rpcSrv.*;
import P9P.type.*;

public abstract class server9P {

   protected pfile root;
   protected int port;
   protected boolean showtraces;
   protected int max_con;
   protected int now_con;
   protected int max_pet;

   public void printMsg(String s) {
      if (showtraces)
         System.out.println(s);
   }

   public abstract void ejecutar();

   protected abstract class threadConnection extends Thread {
      protected fidtable tfid;
      protected DataOutputStream out=null;
      protected DataInputStream in=null;
      protected int con_id;

      public abstract void closeConection();

      public void run() {
         byte[] arraysize = new byte[4];
         byte[] arraytmsg;
         int int_size;
         int9P size=new int9P();
         tmsg9P tmsg;
         rmsg9P rmsg;
         rpc9P rpc;

         printMsg(con_id + " conexion aceptada ...");

         while( true ) {

            try {
               //LEER 4 BYTES
               in.readFully(arraysize);
               size.read(arraysize,0);
               arraytmsg= new byte[(int)size.value-4];
               //LEER RESTO
               in.readFully(arraytmsg);
            }
            catch (IOException e) {
               System.out.println("[read]" + e);
               break;
            }

            tmsg = (tmsg9P) msg9P.setTypeMsg(arraytmsg[0]);
            tmsg.read(arraytmsg,0);
            printMsg(tmsg.toString());

            rpc=rpc9P.getrpc(tmsg);
            rmsg=rpc.process(tfid);
            printMsg(rmsg.toString());

            try {
               out.write(putsize(rmsg));
            }
            catch (IOException e) {
               System.out.println("[write]" + e);
            }
         }
         closeConection();
      }

      private byte[] putsize (msg9P msg) {

         ByteArrayOutputStream buf=new ByteArrayOutputStream();
         ByteArrayOutputStream aux=new ByteArrayOutputStream();
         buf.reset();
         aux.reset();

         msg.write(buf);

         int9P size = new int9P(buf.size()+4);
         size.write(aux);
         aux.write(buf.toByteArray(),0,buf.size());
         return aux.toByteArray();
      }
   }
}