package w3c.rtsp.common;

import java.io.*;
import java.util.*;
import java.net.*;
import java.awt.*;


public class RtspRequest {

  public RequestLine requestline;
  public RequestHeader requestheader;
  public GeneralHeader generalheader;
  public EntityHeader requestentityheader;
  public TransportHeader transportheader=null;
  public String BodyMessage = null;


  public RtspRequest(RequestLine requestline,
		     GeneralHeader GeneralHeader,
		     RequestHeader requestheader,
		     EntityHeader requestentityheader,
		     TransportHeader transportheader,
		     String BodyMessage){
    this.requestline=requestline;
    
    this.generalheader=new GeneralHeader();
    this.generalheader.setConnection(generalheader.getConnection());
    this.generalheader.setDate(new RtspDate(new Date()));
    this.generalheader.setVia(generalheader.getVia());
    this.generalheader.setCacheControl(generalheader.getCacheControl());
    
    this.requestheader=requestheader;
    this.requestentityheader=requestentityheader;
    this.transportheader=transportheader;
    this.BodyMessage=BodyMessage;
  }

  public RtspRequest(String status_header,String body){
      try{
      String method=null,ver=null,ce=null,cla=null;
      int sn=-1,cl=-1,port=-1,sn_len=-1;
      boolean EndRequest=true;
      RtspURL urlR=null;
      // System.out.println("\nline:"+status_header);
      GeneralHeader gh=new GeneralHeader();
      RequestHeader rh=new RequestHeader();
      EntityHeader eh=new EntityHeader();
      TransportHeader th=new TransportHeader();

      while(EndRequest==true){
	//parsing the request line.
	int method_len=status_header.indexOf(' ');
	//	System.out.println("index : "+method_len);
	method = status_header.substring(0,method_len);
	//	System.out.println("\nMethod :"+method);
	int url_len=status_header.indexOf(' ',method_len+1);
	//	System.out.println("index url: "+url_len);
	urlR= new RtspURL(status_header.substring(method_len+1,url_len));
	//	System.out.println("\nurlReq :"+urlR.toString());
	int ver_len=status_header.indexOf(' ',url_len+1);
	//	System.out.println("index ver: "+ver_len);
	ver= status_header.substring(url_len+1,ver_len);
	//	System.out.println("\nVER :"+ver);
	sn_len=status_header.indexOf('\n',ver_len+1);
	//	System.out.println("index sn: "+sn_len);
	sn= Integer.parseInt(status_header.substring(ver_len+1,sn_len-1));
	//	System.out.println("\nSEQ :"+sn);
	EndRequest=false;
      }

      //parsing the general header,request headerentity,header and the Transport Header.

      // System.out.println("index sn: "+sn_len);
      int index=sn_len+1;

      index=isGeneralHeader(gh,status_header,index);
      
      index=isRequestHeader(rh,status_header,index);
      
      index=isEntityHeader(eh,status_header,index);
      
      index=isTransportHeader(th,status_header,index);
      
      // System.out.println("\nTRANSPORT:"+th.getPort()+th.getTransport());
      
      RequestLine rql=new RequestLine(method,urlR,ver,sn);
    
      // EntityHeader rh=new EntityHeader(ce,cla,cl,ct,e,lm,eh);
   
      this.requestline=rql;
      this.generalheader=gh;
      this.requestheader=rh;
      this.requestentityheader=eh;
      this.transportheader=new TransportHeader();      
      if(th!=null){
       	this.transportheader.setTransport(th.getTransport());
	this.transportheader.setPort(th.getPort());
	//	System.out.println("\ntransportheader :"+this.transportheader.getTransport());
      }
      else
	this.transportheader=new TransportHeader();
      this.BodyMessage=body;
      }catch(MalformedURLException E){
	System.out.print("\n URL ERROR : "+E.getMessage());
	E.printStackTrace();
      }
  }

 // return it if exist.

  public String search(String linerq,String it) {
    int beg_ind=0,end_ind=0;

    if(linerq.lastIndexOf(it)!=-1){
      beg_ind=linerq.indexOf(it)+1+it.length();
      try{
	end_ind=linerq.indexOf("\r\n",beg_ind);
	if(beg_ind>0)
	  return linerq.substring(beg_ind,end_ind);
	else 
	  return null;
      }catch(StringIndexOutOfBoundsException E){
	return linerq.substring(beg_ind);
      }
    }
    else 
      return null;
  }
  //parse the contents of the TransportHeader.

  public TransportHeader parseTransportHeader(String myString){
    char trans[]=null,p[]=null,reccord[]=null;
    TransportHeader TH;
    int i=0;
    reccord=myString.toCharArray();
    //  System.out.println("\nRECCORD="+reccord);
    // System.out.println("\nLENGTH="+myString.length());
    while(reccord[i]!=';'){
      i++;
    }
    trans=new char[i+1];
    i=0;
    while(reccord[i]!=';'){
      trans[i]=reccord[i];
      i++;
    }
    while(reccord[i++]!='=')
      ;
    int index=i;
    p=new char[myString.length()-i];
    while(i<myString.length()){
      p[i-index]=reccord[i];
      i++;
    }
    // System.out.println("\nTransport= "+trans+"\nport="+p);
    String myport=new String(p);
    // System.out.println("\nmyport:"+myport);
    return TH=new TransportHeader(new String(trans),Integer.parseInt(myport));
  }
  
 public void emit(PrintWriter output){
   //  System.out.println("REQUESTLINE");
   requestline.emit(output);
   //  System.out.println("GENERAL HEADER");
   this.generalheader.emit(output);
   // System.out.println("HEADER REQUEST");
   requestheader.emit(output);
   // System.out.println("ENTITY REQUEST");
   requestentityheader.setContentLength(BodyMessage.length());
   requestentityheader.emit(output);
  //send the tranport header.
   //  System.out.println("TRANSPORT HEADER");
   transportheader.emit(output);
   output.print("\r\n"); 
   output.print(BodyMessage);
   output.flush();
 }

  //test if the msg contains field of the general header.If yes instanciate the field
  //value and return the index of the end of the last field value.

  public int isGeneralHeader(GeneralHeader genhea,String msg,int beginindex){
    int endindex=beginindex;
    //  System.out.println("\nmessage :"+msg.substring(endindex));
    if(msg.startsWith("Cache-Control:",beginindex)){
      beginindex=msg.indexOf("Cache-Control:",beginindex)+"Cache-Control:".length();
      endindex=msg.indexOf("\r\n",beginindex);
      if(endindex==-1)
	genhea.setCacheControl(msg.substring(beginindex+1));
      else
	genhea.setCacheControl(msg.substring(beginindex+1,endindex));
      endindex+=2;
    }
    if(msg.startsWith("Connection:",endindex)){
      beginindex=msg.indexOf("Connection:",endindex)+"Connection:".length();
      endindex=msg.indexOf("\r\n",beginindex);
      if(endindex==-1)
	genhea.setConnection(msg.substring(beginindex+1));
      else
	genhea.setConnection(msg.substring(beginindex+1,endindex));
      endindex+=2;
    }
    if(msg.startsWith("Date:",endindex)){
      beginindex=msg.indexOf("Date:",endindex)+"Date:".length();
      endindex=msg.indexOf("\r\n",beginindex);
      //   System.out.println("\nDebut champ date:"+msg.substring(beginindex));
      // System.out.println("\nFin champ date:"+endindex);
      if(endindex!=-1)
	genhea.setDate(new RtspDate(msg.substring(beginindex+1,endindex)));
      else
	genhea.setDate(new RtspDate(msg.substring(beginindex+1)));
      // System.out.println("\nDATE OBJECT :"+genhea.getDate().toString());
      endindex+=2;
    }
    if(msg.startsWith("Via",endindex)){
      beginindex=msg.indexOf("Via",endindex)+"Via".length();
      endindex=msg.indexOf("\r\n",beginindex);
      if(endindex!=-1)
	genhea.setVia(msg.substring(beginindex+1,endindex));
      else
	genhea.setVia(msg.substring(beginindex+1));
      endindex+=2;
    }
    return endindex;
  }

  //test if the str is reccord of the Request header.

 public int isRequestHeader(RequestHeader reqhea,String msg,int beginindex){
   int endindex=beginindex;

   if(msg.startsWith("Accept:",beginindex)){
     beginindex=msg.indexOf("Accept:",endindex)+"Accept:".length();
     endindex=msg.indexOf("\r\n",beginindex);
   if(endindex!=-1)
     reqhea.setAccept(msg.substring(beginindex+1,endindex));
   else
     reqhea.setAccept(msg.substring(beginindex+1));
     endindex+=2;
   }
    if(msg.startsWith("Accept-Encoding:",endindex)){
     beginindex=msg.indexOf("Accept-Encoding:",endindex)+"Accept-Encoding:".length();
     endindex=msg.indexOf("\r\n",beginindex);
     if(endindex!=-1)
       reqhea.setAcceptEncoding(msg.substring(beginindex+1,endindex)); 
     else
       reqhea.setAcceptEncoding(msg.substring(beginindex+1)); 
     endindex+=2;
   }
    if(msg.startsWith("Accept-Language:",endindex)){
     beginindex=msg.indexOf("Accept-Language:",endindex)+"Accept-Language:".length();
     endindex=msg.indexOf("\r\n",beginindex);
     if(endindex!=-1)
       reqhea.setAcceptLanguage(msg.substring(beginindex+1,endindex));
     else
       reqhea.setAcceptLanguage(msg.substring(beginindex+1));
     endindex+=2;
   }
    if(msg.startsWith("Authorization:",beginindex)){
     beginindex=msg.indexOf("Authorization:",endindex)+"Authorization:".length();
     endindex=msg.indexOf("\r\n",beginindex);
     if(endindex!=-1)
       reqhea.setAuthorization(msg.substring(beginindex+1,endindex));
     else
       reqhea.setAuthorization(msg.substring(beginindex+1));
     endindex+=2;
   }
    if(msg.startsWith("BandWidth:",endindex)){
     beginindex=msg.indexOf("BandWidth:",endindex)+"BandWidth:".length();
     endindex=msg.indexOf("\r\n",beginindex);
     if(endindex!=-1)
       reqhea.setBandWidth(Integer.parseInt(msg.substring(beginindex+1,endindex)));
     else
       reqhea.setBandWidth(Integer.parseInt(msg.substring(beginindex+1)));
     endindex+=2;
   }
    if(msg.startsWith("BlockSize:",endindex)){
     beginindex=msg.indexOf("BlockSize:",endindex)+"BlockSize:".length();
     endindex=msg.indexOf("\r\n",beginindex);
     if(endindex!=-1)
       reqhea.setBlockSize(Integer.parseInt(msg.substring(beginindex+1,endindex)));
     else
       reqhea.setBlockSize(Integer.parseInt(msg.substring(beginindex+1)));
     endindex+=2;
   }
    if(msg.startsWith("Conference:",endindex)){
      beginindex=msg.indexOf("Conference:",endindex)+"Conference:".length();
      endindex=msg.indexOf("\r\n",beginindex);
      if(endindex!=-1)
	reqhea.setConference(msg.substring(beginindex+1,endindex));
      else
	reqhea.setConference(msg.substring(beginindex+1));
      endindex+=2;
    }
    if(msg.startsWith("If-Modified-Since:",endindex)){
      beginindex=msg.indexOf("If-Modified-Since:",endindex)+"If-Modified-Since:".length();
      endindex=msg.indexOf("\r\n",beginindex);
      if(endindex!=-1)
	reqhea.setIfModifiedSince(new RtspDate(msg.substring(beginindex+1,endindex)));
      else
	reqhea.setIfModifiedSince(new RtspDate(msg.substring(beginindex+1)));
      endindex+=2;
    }
    if(msg.startsWith("Range:",endindex)){
      beginindex=msg.indexOf("Range:",endindex)+"Range:".length();
      endindex=msg.indexOf("\r\n",beginindex);
     if(endindex!=-1)
       reqhea.setRange(msg.substring(beginindex+1,endindex));
       else
	 reqhea.setRange(msg.substring(beginindex+1));
      endindex+=2;
    }
    if(msg.startsWith("Referer:",endindex)){
      beginindex=msg.indexOf("Referer:",endindex)+"Referer:".length();
      endindex=msg.indexOf("\r\n",beginindex);
      if(endindex!=-1)
	reqhea.setReferer(msg.substring(beginindex+1,endindex));
      else
	reqhea.setReferer(msg.substring(beginindex+1));
      endindex+=2;
    }
    if(msg.startsWith("Scale:",endindex)){
      beginindex=msg.indexOf("Scale:",endindex)+"Scale:".length();
      endindex=msg.indexOf("\r\n",beginindex);
      if(endindex!=-1)
	reqhea.setScale(Integer.parseInt(msg.substring(beginindex+1,endindex)));
      else
	reqhea.setScale(Integer.parseInt(msg.substring(beginindex+1)));
      endindex+=2;
    }
    if(msg.startsWith("Session:",endindex)){
      beginindex=msg.indexOf("Session:",endindex)+"Session:".length();
      endindex=msg.indexOf("\r\n",beginindex);
      if(endindex!=-1)
	reqhea.setSession(Integer.parseInt(msg.substring(beginindex+1,endindex)));
      else
	reqhea.setSession(Integer.parseInt(msg.substring(beginindex+1)));
      // System.out.println("\nSESSION : "+reqhea.getSession());
      endindex+=2;
    }
    if(msg.startsWith("Speed:",endindex)){
      beginindex=msg.indexOf("Speed:",endindex)+"Speed:".length();
      endindex=msg.indexOf("\r\n",beginindex);
      if(endindex!=-1)
	reqhea.setSpeed(Integer.parseInt(msg.substring(beginindex+1,endindex)));
      else
	reqhea.setSpeed(Integer.parseInt(msg.substring(beginindex+1)));
      endindex+=2;
    }
    if(msg.startsWith("User-Agent:",endindex)){
      beginindex=msg.indexOf("User-Agent:",endindex)+"User-Agent:".length();
      endindex=msg.indexOf("\r\n",beginindex);
      if(endindex!=-1)
	reqhea.setUserAgent(msg.substring(beginindex+1,endindex));
      else
	reqhea.setUserAgent(msg.substring(beginindex+1));
      endindex+=2;
    }
    return endindex;
 }
  
  //test if the str is reccord of the Entity header.
   
  public int isEntityHeader(EntityHeader enthea,String msg,int beginindex){
    int endindex=beginindex;
    if(msg.startsWith("Allow:",beginindex)){
      beginindex=msg.indexOf("Allow:",beginindex)+"Allow:".length();
      endindex=msg.indexOf("\r\n",beginindex);
      if(endindex!=-1)
	enthea.setAllow(msg.substring(beginindex+1,endindex));
      else
	enthea.setAllow(msg.substring(beginindex+1));
      endindex+=2;
    }
    if(msg.startsWith("Content-Encoding:",endindex)){
      // System.out.println("\nmessage contentEncoding :"+msg.substring(endindex));
      beginindex=msg.indexOf("Content-Encoding:",endindex)+"Content-Encoding:".length();
      endindex=msg.indexOf("\r\n",beginindex);
      if(endindex!=-1)
	enthea.setContentEncoding(msg.substring(beginindex+1,endindex));
      else
	enthea.setContentEncoding(msg.substring(beginindex+1));
      // System.out.println("\ncontentEncoding:"+msg.substring(beginindex+1,endindex));
      endindex+=2;
    }
    if(msg.startsWith("Content-Language:",endindex)){
      beginindex=msg.indexOf("Content-Language:",endindex)+"Content-Language:".length();
      endindex=msg.indexOf("\r\n",beginindex);
      if(endindex!=-1)
	enthea.setContentLanguage(msg.substring(beginindex+1,endindex));
     else
       enthea.setContentLanguage(msg.substring(beginindex+1));
      endindex+=2;
    }
    if(msg.startsWith("Content-Length:",endindex)){
      beginindex=msg.indexOf("Content-Length:",endindex)+"Content-Length:".length();
      endindex=msg.indexOf("\r\n",beginindex);
      if(endindex==-1)
	enthea.setContentLength(Integer.parseInt(msg.substring(beginindex+1)));
      else
	enthea.setContentLength(Integer.parseInt(msg.substring(beginindex+1,endindex)));
      endindex+=2;
    }
    if(msg.startsWith("Content-Type:",endindex)){
      beginindex=msg.indexOf("Content-Type:",endindex)+"Content-Type:".length();
      endindex=msg.indexOf("\r\n",beginindex);
      if(endindex==-1)
	enthea.setContentType(msg.substring(beginindex+1,endindex));
      else
	enthea.setContentType(msg.substring(beginindex+1));
      endindex+=2;
    }
    if(msg.startsWith("Expires:",endindex)){
      beginindex=msg.indexOf("Expires:",endindex)+"Expires:".length();
      endindex=msg.indexOf("\r\n",beginindex);
      if(endindex==-1)
	enthea.setExpires(msg.substring(beginindex+1,endindex));
      else
	enthea.setExpires(msg.substring(beginindex+1));
      endindex+=2;
    }
    if(msg.startsWith("Last-Modified:",endindex)){
      beginindex=msg.indexOf("Last-Modified:",endindex)+"Last-Modified:".length();
      endindex=msg.indexOf("\r\n",beginindex);
      if(endindex==-1)
	enthea.setLastModified(msg.substring(beginindex+1,endindex));
      else
	enthea.setLastModified(msg.substring(beginindex+1));
      endindex+=2;
    }
    if(msg.startsWith("Extension-Header:",endindex)){
      beginindex=msg.indexOf("Extension-Header:",endindex)+"Extension-Header:".length();
      endindex=msg.indexOf("\r\n",beginindex);
      if(endindex==-1)
	enthea.setExtensionHeader(msg.substring(beginindex+1,endindex));
      else
	enthea.setExtensionHeader(msg.substring(beginindex+1));
      endindex+=2;
    }
    return endindex;
  }

  public int isTransportHeader(TransportHeader trahea,String msg,int beginindex){
    int endindex=beginindex;
    TransportHeader tmp=new TransportHeader();
    if(msg.startsWith("Transport:",beginindex)){
      beginindex=msg.indexOf("Transport:",beginindex)+"Transport:".length();
      endindex=msg.indexOf("\r\n",beginindex);
      // System.out.println("\nDEBUT INDEX TRANSPORT:"+beginindex);
      //System.out.println("\nEND INDEX TRANSPORT:"+endindex);
      // System.out.println("\nTRANSPORT :"+msg.substring(beginindex+1));//,endindex));
      if(endindex==-1){
	tmp=parseTransportHeader(msg.substring(beginindex+1));
	//System.out.println("\nTRANSPORT trans:"+tmp.getTransport());
	trahea.setTransport(tmp.getTransport());
	trahea.setPort(tmp.getPort());
	//	System.out.println("\nAVANT:"+trahea.getPort());
      }
      else
	trahea=parseTransportHeader(msg.substring(beginindex+1,endindex));
      endindex+=2;
    }
    return endindex;
  }
}

   



