/*
 *  Licensed to the Apache Software Foundation (ASF) under one
 *  or more contributor license agreements.  See the NOTICE file
 *  distributed with this work for additional information
 *  regarding copyright ownership.  The ASF licenses this file
 *  to you under the Apache License, Version 2.0 (the
 *  "License"); you may not use this file except in compliance
 *  with the License.  You may obtain a copy of the License at
 * 
 *  http://www.apache.org/licenses/LICENSE-2.0
 * 
 *  Unless required by applicable law or agreed to in writing,
 *  software distributed under the License is distributed on an
 *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 *  KIND, either express or implied.  See the License for the
 *  specific language governing permissions and limitations
 *  under the License.
 */
package org.apache.myfaces.buildtools.maven2.plugin.xrts;

import java.util.Map;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Set;

import org.xml.sax.AttributeList;
import org.xml.sax.HandlerBase;
import org.xml.sax.Locator;
import org.xml.sax.SAXException;

/**
 * */
final class XRTSParser extends HandlerBase
{

  /**
   * Empty constructor for the XRTSParser
   *
   */
  public XRTSParser()
  {
  }

  public XRTSParser(RTSWriter bw, Map parms)
  {
    _bundleWriter = bw;
    _parms = parms;
  }

  /**
   * Receive a Locator object for document events.
   * Setting Locator ensures the SAX parser can find a given XML-based RTS
   * document.  This method is closely related to the _fileToURL in
   * <code>XRTSMakeBundle</code>.
   *
   * @param locator A locator for all SAX document events.
   */
  public void setDocumentLocator (Locator locator)
  {
    _locator = locator;
  }

  /**
   * Receive notification of the beginning of the document.
   * SAX Parser event for finding the beginning of an XML-based RTS document
   */
  public void startDocument() throws SAXException
  {
    _metaHt.put("fileType", "xrts");
    _startDoc = true;

  }

  /**
   * Receive notification of the end of the document.
   * SAX Parser event for finding the end of an XML-based RTS document
   */
  public void endDocument() throws SAXException
  {
//    System.out.println("EndDocument");
    try
    {
      _bundleWriter.endBundle(_parms, _metaHt);
    }
    catch (Throwable th)
    {
      throw new SAXException("endBundle Exception: " + th.getMessage());
    }
  }

  /**
   * Receive notification of the start of an element.
   *
   * @param name the element type name.
   * @param attributes the specified or defaulted attributes.
   */
  public void startElement(String name, AttributeList atts) throws SAXException
  {
    _nestingLevel++;

    // startBundle doesn't go in the startDocument method because it
    // requires metadata to be passed and in particular, requires
    // at least the package for any implementation of startBundle to work
    if ((_nestingLevel == 2) && name.equals("resource"))
    {
      if (_startDoc)
      {
        try
        {
          _bundleWriter.startBundle(_parms, _metaHt);
          _startDoc = false;
        }
        catch (Throwable th)
        {
          throw new SAXException("startBundle Exception: " + th.getMessage());
        }
      }

      _currentResourceKey = atts.getValue("key");
      if (_uniqKeys.contains(_currentResourceKey))
      {
        System.err.println("Duplicate id \"" + _currentResourceKey + "\"");
      }

      _uniqKeys.add(_currentResourceKey);
      

      _currentResourceValue = new StringBuilder();
    }
    else if ((_nestingLevel == 1) && name.equals("resources"))
    {
      _metaHt.put("package", atts.getValue("package"));
      if (atts.getValue("version") != null)
      {
        _metaHt.put("version", atts.getValue("version"));
      }
      if (atts.getValue("baseversion") != null)
      {
        _metaHt.put("baseVersion", atts.getValue("baseversion"));
      }
    }
  }

  /**
   * Receive notification of the end of an element.
   * @param name the element type name.
   */
  public void endElement(String name) throws SAXException
  {
    if ((_nestingLevel == 2) && name.equals("resource"))
    {
      String value = _currentResourceValue.toString().trim();
      try
      {
        _bundleWriter.writeString(_parms, _metaHt, _currentResourceKey, value);
      }
      catch (Throwable t)
      {
        throw new SAXException(t.getMessage());
      }
    }

    _nestingLevel--;
  }

  /**
   * Receive notification of ignorable whitespace in element content.
   *
   * @param ch the whitespace characters.
   * @param start the start position in the character array.
   * @param length the number of characters to use from the character array.
   */
  public void ignorableWhitespace(char[] cbuf, int start, int len)
    throws SAXException
  {
//    System.out.println("IgnorableWhiteSpace" + len);
  }

  /**
   * Receive notification of character data inside an element.
   *
   * @param ch the characters.
   * @param start the start position in the character array.
   * @param length the number of characters to use from the character array.
   */
  public void characters(char[] cbuf, int start, int len) throws SAXException
  {
    if (_nestingLevel == 2)
    {
      _currentResourceValue.append(cbuf, start, len);
    }
  }


  // Store the locator
  private Locator _locator;

  private String _currentResourceKey;
  private StringBuilder _currentResourceValue;
  private Map<String, Object> _metaHt = new HashMap<String, Object>();
  private Set<String> _uniqKeys = new HashSet<String>();

  private RTSWriter _bundleWriter;
  private Map _parms;

  private int _nestingLevel = 0;
  private boolean _startDoc = false;
}
