//______________________________________________________________________________
//   |       |
//   | knipp |           Knipp Medien und Kommunikation GmbH
//    -------
//
//
//     Knipp RRI Toolkit
//
//
//     Copyright (C) 2005 by Knipp Medien und Kommunikation GmbH
//
//     This library is free software; you can redistribute it and/or
//     modify it under the terms of the GNU Lesser General Public License 
//     as published by the Free Software Foundation; either version 2.1 
//     of the License, or any later version.
// 
//     This library 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 Lesser General Public License for more details.
//
//     You should have received a copy of the GNU Lesser General
//     Public License along with this library; if not, write to the 
//     Free Software Foundation, Inc., 59 Temple Place, Suite 330, 
//     Boston, MA 02111-1307 USA 
//
//
//     initial author:    Klaus Malorny
//
//     version:           1.4 (15127), 2011/06/03 14:52:49
//                        $Revision: 14936 $ 
//                        $Date: 2010-11-05 15:57:40 +0100 (Fri, 05 Nov 2010) $
//                        $Author: Klaus.Malorny $
//

package de.knipp.rritoolkit.response;

import java.util.Map;
import java.util.HashMap;

import org.w3c.dom.Element;
import org.w3c.dom.DOMException;

import de.knipp.rritoolkit.KVList;
import de.knipp.rritoolkit.KVMultiList;
import de.knipp.rritoolkit.ResponseParseException;

import static de.knipp.rritoolkit.DenicConstants.NS_CONTACT;

import static de.knipp.rritoolkit.XmlHelper.getFirstElement;
import static de.knipp.rritoolkit.XmlHelper.getFirstElementText;


/**
 *  response of a contact check request
 *
 *  @version  $Revision: 14936 $
 *  @author   Klaus Malorny
 */

public class ContactCheckResponse extends Response
{
  /** the handle */
  
  private String handle;
  
  
  /** the status */
  
  private State state;
  
  
  
  //--- implementation of Response ---------------------------------------------
  
  
  /**
   *  subclasses that need to read additional data from the key-value pair
   *  response should override this method. The default implementation is empty 
   *  and need not to be called.
   *
   *  @param list                     the list
   *  @throws ResponseParseException  if the document does not contain the
   *                                  expected content
   */

  @Override
  protected void dataFromList (KVMultiList list)
    throws ResponseParseException
  {
    if (isSuccess ())
    {
      KVList main = list.getMainSection ();
      handle = main.getFirst ("handle");
      String temp = main.getFirst ("status");
      
      if (temp != null)
      {
        state = State.fromToken (temp);
        
        if (state == null) 
          throw new ResponseParseException ("invalid status", "status", temp);
        
      } else
      {
        state = null;
      }
    }
  }

  /**
   *  subclasses that need to read additional data from the XML response should
   *  override this method. The default implementation is empty and need not
   *  to be called.
   *
   *  @param data                     the data element or {@code null}
   *                                  if the data contains no additional data
   *  @throws DOMException            on DOM exceptions
   *  @throws ResponseParseException  if the document does not contain the
   *                                  expected content
   */

  @Override
  protected void dataFromXml (Element data)
    throws DOMException, ResponseParseException
  {
    if (data != null && isSuccess ())
    {
      Element el = getFirstElement (data, NS_CONTACT, "checkData");
      
      if (el != null)
      {
        handle = getFirstElementText (el, NS_CONTACT, "handle");
        String temp = getFirstElementText (el, NS_CONTACT, "status");

        if (temp != null)
        {
          state = State.fromToken (temp);
          
          if (state == null) 
            throw new ResponseParseException ("invalid status", 
              getFirstElement (el, NS_CONTACT, "status"));

        } else
        {
          state = null;
        }
      }
    }
  }
  
  /**
   *  call the suitable method of the given visitor
   *
   *  @param visitor               the visitor
   */
  
  @Override
  public void accept (ResponseVisitor visitor)
  {
    visitor.visit (this);
  }
  
  
  
  
  /**
   *  return a string representation for debugging purposes
   *
   *  @return                      the string representation
   */
  
  @Override
  public String toString ()
  {
    return super.toString () + "  handle: " + handle + 
      "\n  state: " + state + "\n";
  }  
  
  
  

  
  //--- access methods ---------------------------------------------------------
  
  /**
   *  return the handle
   *
   *  @return             the handle, or {@code null} in case of an error
   */
  
  public String getHandle ()
  {
    return handle;
  }
  
  
  /**
   *  return the status
   *
   *  @return            the state or {@code null} in case of an error
   */
  
  public State getState ()
  {
    return state;
  }
  
  
  
  /**
   *  enumeration for the different states
   *
   *  @version  $Revision: 14936 $
   *  @author   Klaus Malorny
   */
  
  public static enum State
  {
    /** contact handle is free */

    Free ("free"),


    /** contact handle exists */

    Exists ("exist"),


    /** contact handle is invalid */

    Invalid ("invalid");

    /** the DENIC token */
    
    private String denicToken;
    
    
    /** map from the token to the type */
    
    private static final Map<String, State> tokenMap;
    
    
    static
    {
      tokenMap = new HashMap<String, State> ();
      
      for (State s: values ()) 
        tokenMap.put (s.denicToken.toLowerCase (), s);
    }
    
    /**
     *  constructor
     *
     *  @param token               the token that is used in DENIC messages
     *                             for representing the level
     */
    
    private State (String token)
    {
      denicToken = token;
    }
 
    
    /**
     *  returns the DENIC token
     *
     *  @return                     the token
     */
    
    public String getDenicToken ()
    {
      return denicToken;
    }
    
    
    
    /**
     *  returns the state for the given token
     *
     *  @param denicToken           the token
     *  @return                     the state, or {@code null} if the
     *                              token is not found
     */
    
    public static State fromToken (String denicToken)
    {
      return tokenMap.get (denicToken.toLowerCase ());
    }
  }
  
}
