//______________________________________________________________________________
//   |       |
//   | 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: 15115 $ 
//                        $Date: 2011-05-27 16:25:37 +0200 (Fri, 27 May 2011) $
//                        $Author: Klaus.Malorny $
//

package de.knipp.rritoolkit.dns;

import java.util.regex.Pattern;
import java.util.regex.Matcher;

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

import de.knipp.rritoolkit.KVList;
import de.knipp.rritoolkit.XmlBuilder;
import de.knipp.rritoolkit.ResponseParseException;
import de.knipp.rritoolkit.EncodeException;

import static de.knipp.rritoolkit.DenicConstants.NS_DNS_ENTRY;
import static de.knipp.rritoolkit.DenicConstants.NS_XSI;
import static de.knipp.rritoolkit.DenicConstants.PREFIX_DNS_ENTRY;
import static de.knipp.rritoolkit.DenicConstants.PREFIX_XSI;

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


/**
 *  class that describes an "MX" record in the domain.
 *
 *  @version  $Revision: 15115 $
 *  @author   Klaus Malorny
 */

public class DnsEntryMX extends DnsEntry
{
  /** the priority */
  
  private int preference;
  
  
  /** the domain name of the mail exchange server */
  
  private String mailExchangeName;
  
  
  
  /** the pattern to parse the contents of the value */
  
  private static final Pattern parsePattern = Pattern.compile (
    "(\\d{1,5})\\s+(\\S+)", Pattern.CASE_INSENSITIVE);
  
  
  
  /**
   *  constructor
   *
   *  @param theOwner                    the owner
   *  @param thePreference               the preference
   *  @param exchangeName                the name of the mail exchange
   */
  
  public DnsEntryMX (String theOwner, int thePreference, String exchangeName)
  {
    setOwner (theOwner);
    preference = thePreference;
    mailExchangeName = exchangeName;
  }
  
  
  /**
   *  constructor
   *
   *  @param owner                       the owner
   *  @param value                       the rdata part of the entry
   *  @throws ResponseParseException     on parsing problems
   */
  
  protected DnsEntryMX (String owner, String value)
    throws ResponseParseException
  {
    Matcher m = parsePattern.matcher (value);
    
    if (!m.matches ())
      throw new ResponseParseException ("invalid MX record", value);
    
    setOwner (owner);
    preference = Integer.parseInt (m.group (1));
    mailExchangeName = m.group (2);
  }
  
  
  /**
   *  constructor
   *
   *  @param el                       the element
   *  @throws DOMException            on DOM exceptions
   *  @throws ResponseParseException  on wrong content
   */
  
  protected DnsEntryMX (Element el)
    throws DOMException, ResponseParseException
  {
    String owner = getFirstElementText (el, NS_DNS_ENTRY, "owner");
    
    if (owner == null)
      throw new ResponseParseException ("missing <owner> element", el);
      
    Element rdata = getFirstElement (el, NS_DNS_ENTRY, "rdata");

    if (rdata == null)
      throw new ResponseParseException ("missing <rdata> element", el);
    
    String pref = getFirstElementText (rdata, NS_DNS_ENTRY, "preference");
    
    if (pref == null)
      throw new ResponseParseException ("missing <preference> element", rdata);
    
    String exch = getFirstElementText (rdata, NS_DNS_ENTRY, "exchange");
    
    if (exch == null)
      throw new ResponseParseException ("missing <exchange> element", rdata);
    
    setOwner (owner);
    preference = Integer.parseInt (pref.trim ());
    mailExchangeName = exch;
  }
  
  

  
  /**
   *  convert the instance to an entry in the given list
   *
   *  @param list                     the list
   *  @throws EncodeException         if the encoding fails
   */

  @Override
  public void toList (KVList list)
    throws EncodeException
  {
    list.add ("nsentry", getOwner () + " IN MX " + 
      preference + " " + mailExchangeName);
  }
  
  
  
  /**
   *  convert the instance to XML
   *
   *  @param node                     the node to append to
   *  @param encodedDomainName        the encoded domain name from the domain
   *                                  info data
   *  @throws DOMException            on DOM exceptions
   *  @throws EncodeException         if the encoding fails
   */

  @Override
  public void toXml (Node node, String encodedDomainName)
    throws DOMException, EncodeException
  {
    XmlBuilder xb = new XmlBuilder (node);
    
    xb.es (NS_DNS_ENTRY, PREFIX_DNS_ENTRY, "dnsentry");
    
    Node current = xb.getCurrent ();
    String prefix = current.getPrefix ();
    
    xb.attr (NS_XSI, PREFIX_XSI, "type", 
      prefix.length () > 0 ? prefix + ":MX" : "MX");
    
    xb.
      elt (NS_DNS_ENTRY, PREFIX_DNS_ENTRY, "owner", getOwner () == null ? 
        encodedDomainName : getOwner ()).
      es (NS_DNS_ENTRY, PREFIX_DNS_ENTRY, "rdata").
      elt (NS_DNS_ENTRY, PREFIX_DNS_ENTRY, "preference", preference).
      elt (NS_DNS_ENTRY, PREFIX_DNS_ENTRY, "exchange", mailExchangeName).
      ee ().
      ee ();
  }

  
  /**
   *  accept the given visitor
   *
   *  @param visitor                  the visitor
   */

  @Override
  public void accept (DnsEntryVisitor visitor)
  {
    visitor.visit (this);
  }
  
  

 
  /**
   *  create a clone of this instance.
   *
   *  @return                         the clone
   */

  @Override
  public DnsEntryMX clone ()
  {
    return (DnsEntryMX) super.clone ();
  }
  
  
  
  /**
   *  create a string representation (for debugging purposes)
   *
   *  @return                    the string representation
   */

  @Override
  public String toString ()
  {
    return getOwner () + " MX " + preference + " " + mailExchangeName;
  }

  
  
  //--- accesss methods --------------------------------------------------------
  
  /**
   *  return the priority
   *
   *  @return                       the priority
   */
  
  public int getPreference ()
  {
    return preference;
  }
  
  
  
  
  
  /**
   *  return the exchange server name
   *
   *  @return                       the name of the exchange server
   */
  
  public String getMailExchangeName ()
  {
    return mailExchangeName;
  }
  
 
}
