
// ChatServlet.java
// Andrew Davison, April 2005, ad@fivedots.coe.psu.ac.th

/* Diskusní server ve formě servletu.

   Zprávy od klientů přijímá jako argumenty své URL-adresy
   (tj. metodou GET.)


  Zprávy klientů:
    * ChatServlet?cmd=hi&name=??         
        // pozdrav žádá o připojení k diskusní skupině. Server
           vrátí uid cookie, nebo klienta odmítne.

    * ChatServlet?cmd=bye&name=?? + uid cookie
        // rozloučení signalizuje odchod klienta

    * ChatServlet?cmd=who
       // nevyžaduje jméno ani cookie. vrátí seznam aktuálně přihlášených 
          klientů

    * ChatServlet?cmd=msg&name=??&msg=?? + uid cookie
        // přidá příspěvek do seznamu

    * ChatServlet?cmd=read&name=??  + uid cookie
        // požádá o všechny veřejné příspěvky uložené na server od posledního
           čtení

  Většina zpráv vyžaduje jméno a UID uživatele pro identifikaci klienta.
  UID klient obdrží po zprávě "hi".

  Informace na straně serveru zahrnují údaje o každém z klientů
  (jméno, uid a počet přečtenýc zpráv) a seznam diskusních příspěvků.
  Údaje uchovává objekt typu ChatGroup.
*/

import javax.servlet.*;
import javax.servlet.http.*;
import java.io.*;


public class ChatServlet extends HttpServlet 
{
   private ChatGroup cg;   // pro uložení informací o klientovi

   public void init() throws ServletException
   {  cg = new ChatGroup();  }


   public void doGet( HttpServletRequest request,
                      HttpServletResponse response )
      throws ServletException, IOException
   // rozhodni se dle parametru cmd, kterou zprávu klient odeslal
   {
     String command = request.getParameter("cmd");
     System.out.println("Příkaz: " + command);

     if (command.equals("hi"))
       processHi(request, response);
     else if (command.equals("bye"))
       processBye(request, response);
     else if (command.equals("who"))
       processWho(response);
     else if (command.equals("msg"))
       processMsg(request, response);
     else if (command.equals("read"))
       processRead(request, response);
     else
       System.out.println("Danému příkazu nerozumím: " + command);
   }  // konec metody: doGet()



  private void processHi(HttpServletRequest request,
                         HttpServletResponse response)
    throws IOException
  /* Formát zprávy: ChatServlet?cmd=hi&name=??  
       
    Klient se chce připojit k diskusní skupině.
    Server vrátí uid cookie nebo klienta odmítne.
  */
  {
    int uid = -1;  // výchozí hodnota pro selhání
    String userName = request.getParameter("name");

    if (userName != null)
      uid = cg.addUser(userName);  // pokus se přidat klienta do skupiny

    if (uid != -1) {  // požadavek byl přijat
      Cookie c = new Cookie("uid", ""+uid);
      response.addCookie(c);
    }
      
    PrintWriter output = response.getWriter();
    if (uid != -1)
      output.println("ok");
    else
      output.println("no");  // požadavek byl odmítnut
    output.close();
  }  // konec metody: processHi()



  private void processBye(HttpServletRequest request,
                         HttpServletResponse response)
    throws IOException
  /* Formát zprávy: ChatServlet?cmd=bye&name=?? + uid cookie

     Klient odchází. Dle jména a cookie smaž jeho údaje.
  */
  {
    boolean isDeleted = false;   // výchozí hodnota pro selhání
    String userName = request.getParameter("name");

    if (userName != null) {
      int uid = getUidFromCookie(request);
      isDeleted = cg.delUser(userName, uid);
    }

    PrintWriter output = response.getWriter();
    if (isDeleted)
      output.println("ok");
    else
      output.println("no");   // smazání se nezdařilo
    output.close();
  }  // konec metody: processBye()



  private int getUidFromCookie(HttpServletRequest request)
  // vrátí hodnotu uid z cookie nebo -1
  {
    Cookie[] cookies = request.getCookies();
    Cookie c;
    for(int i=0; i < cookies.length; i++) {
      c = cookies[i];
      if (c.getName().equals("uid")) {
        try {
          return Integer.parseInt( c.getValue() ); 
        }
        catch (Exception ex){ 
          System.out.println(ex);
          return -1;
        } 
      }
    } 
    return -1;
  } // konec metody: getUidFromCookie()



  private void processWho(HttpServletResponse response)
    throws IOException
  /* Formát zprávy: ChatServlet?cmd=who
       
     Vrátí seznam aktuálně přihlášených klientů.
     Klient nemusí posílat jméno ani cookie.
  */
  { PrintWriter output = response.getWriter();
    output.print( cg.who() );    // již obsahuje znak '\n'
    output.close();
  }  // konec metody: processWho()



  private void processMsg(HttpServletRequest request,
                         HttpServletResponse response)
    throws IOException
  /* Formát zprávy: 
       ChatServlet?cmd=msg&name=??&msg=?? + uid cookie

     Přidá zprávu do seznamu.
  */
  {
    boolean isStored = false;   // výchozí hodnota pro selhání
    String userName = request.getParameter("name");
    String msg = request.getParameter("msg");

    System.out.println("zpráva: " + msg);

    if ((userName != null) && (msg != null)) {
      int uid = getUidFromCookie(request);
      isStored = cg.storeMessage(userName, uid, msg);  // přidej zprávu do seznamu
    }

    PrintWriter output = response.getWriter();
    if (isStored)
      output.println("ok");
    else
      output.println("no");   // něco je špatně
    output.close();
  }  // konec metody: processBye()



  private void processRead(HttpServletRequest request,
                         HttpServletResponse response)
    throws IOException
  /* Formát zprávy: ChatServlet?cmd=read&name=??  + uid cookie

     Všechny veřejné příspěvky uložené na serveru od posledního
     čtení tímto uživatele mu pošle zpět.
  */
  { int uid = -1;   // výchozí hodnota pro selhání
    String userName = request.getParameter("name");

    if (userName != null)
      uid = getUidFromCookie(request);

    PrintWriter output = response.getWriter();
    if (uid != -1) {
      output.print( cg.read(userName, uid) );   // již má znak '\n'
      output.flush();
    }
    else
      output.println("no");   // něco je špatně
    output.close();
  }  // konec metody: processRead()


} // konec třídy: ChatServlet

