/* Copyright (C) 2021 Free Software Foundation, Inc.
   Contributed by Oracle.

   This file is part of GNU Binutils.

   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
   the Free Software Foundation; either version 3, or (at your option)
   any later version.

   This program 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 General Public License for more details.

   You should have received a copy of the GNU General Public License
   along with this program; if not, write to the Free Software
   Foundation, 51 Franklin Street - Fifth Floor, Boston,
   MA 02110-1301, USA.  */

#include "config.h"
#include <ctype.h>

#include "util.h"
#include "vec.h"
#include "DefaultHandler.h"
#include "SAXParser.h"
#include "SAXParserFactory.h"
#include "StringBuilder.h"

/*
 *  Private implementation of Attributes
 */
class AttributesP : public Attributes
{
public:
  AttributesP ();
  ~AttributesP ();
  int getLength ();
  const char *getQName (int index);
  const char *getValue (int index);
  int getIndex (const char *qName);
  const char *getValue (const char *qName);
  void append (char *qName, char *value);

private:
  Vector<char*> *names;
  Vector<char*> *values;
};

AttributesP::AttributesP ()
{
  names = new Vector<char*>;
  values = new Vector<char*>;
}

AttributesP::~AttributesP ()
{
  Destroy (names);
  Destroy (values);
}

int
AttributesP::getLength ()
{
  return names->size ();
}

const char *
AttributesP::getQName (int index)
{
  if (index < 0 || index >= names->size ())
    return NULL;
  return names->fetch (index);
}

const char *
AttributesP::getValue (int index)
{
  if (index < 0 || index >= values->size ())
    return NULL;
  return values->fetch (index);
}

int
AttributesP::getIndex (const char *qName)
{
  for (int idx = 0; idx < names->size (); idx++)
    if (strcmp (names->fetch (idx), qName) == 0)
      return idx;
  return -1;
}

const char *
AttributesP::getValue (const char *qName)
{
  for (int idx = 0; idx < names->size (); idx++)
    if (strcmp (names->fetch (idx), qName) == 0)
      return values->fetch (idx);
  return NULL;
}

void
AttributesP::append (char *qName, char *value)
{
  names->append (qName);
  values->append (value);
}

/*
 *  Implementation of SAXException
 */
SAXException::SAXException ()
{
  message = strdup ("null");
}

SAXException::SAXException (const char *_message)
{
  if (_message == NULL)
    message = strdup ("null");
  else
    message = strdup (_message);
}

SAXException::~SAXException ()
{
  free (message);
}

char *
SAXException::getMessage ()
{
  return message;
}

/*
 *  SAXParseException
 */
SAXParseException::SAXParseException (char *message, int _lineNumber, int _columnNumber)
: SAXException (message == NULL ? GTXT ("XML parse error") : message)
{
  lineNumber = _lineNumber;
  columnNumber = _columnNumber;
}

/*
 *  Private implementation of SAXParser
 */
class SAXParserP : public SAXParser
{
public:
  SAXParserP ();
  ~SAXParserP ();
  void reset ();
  void parse (File*, DefaultHandler*);

  bool
  isNamespaceAware ()
  {
    return false;
  }

  bool
  isValidating ()
  {
    return false;
  }

private:

  static const int CH_EOF = -1;

  void nextch ();
  bool isWSpace ();
  void skipWSpaces ();
  void scanString (const char *str);
  char *parseName ();
  char *parseString ();
  char *decodeString (char *str);
  Attributes *parseAttributes ();
  void parseTag ();
  void parseDocument ();
  void parsePart (int idx);

  DefaultHandler *dh;
  int bufsz;
  char *buffer;
  int cntsz;
  int idx;
  int curch;
  int line;
  int column;
};

SAXParserP::SAXParserP ()
{
  dh = NULL;
  bufsz = 0x2000;
  buffer = (char*) malloc (bufsz);
  cntsz = 0;
  idx = 0;
  line = 1;
  column = 0;
}

SAXParserP::~SAXParserP ()
{
  free (buffer);
}

void
SAXParserP::reset ()
{
  dh = NULL;
  bufsz = 8192;
  buffer = (char*) realloc (buffer, bufsz);
  cntsz = 0;
  idx = 0;
  line = 1;
  column = 0;
}

void
SAXParserP::parse (File *f, DefaultHandler *_dh)
{
  if (_dh == NULL)
    return;
  dh = _dh;
  FILE *file = (FILE*) f;
  int rem = bufsz;
  cntsz = 0;
  idx = 0;
  for (;;)
    {
      int n = (int) fread (buffer + cntsz, 1, rem, file);
      if (ferror (file) || n <= 0)
	break;
      cntsz += n;
      if (feof (file))
	break;
      rem -= n;
      if (rem == 0)
	{
	  int oldbufsz = bufsz;
	  bufsz = bufsz >= 0x100000 ? bufsz + 0x100000 : bufsz * 2;
	  buffer = (char*) realloc (buffer, bufsz);
	  rem = bufsz - oldbufsz;
	}
    }
  nextch ();
  parseDocument ();
}

static int
hex (char c)
{
  if (c >= '0' && c <= '9')
    return (c - '0');
  else if (c >= 'a' && c <= 'f')
      return 10 + (c - 'a');
  return -1;
}

void
SAXParserP::nextch ()
{
  curch = idx >= cntsz ? CH_EOF : buffer[idx++];
  if (curch == '\n')
    {
      line += 1;
      column = 0;
    }
  else
    column += 1;
}

bool
SAXParserP::isWSpace ()
{
  return curch == ' ' || curch == '\t' || curch == '\n' || curch == '\r';
}

void
SAXParserP::skipWSpaces ()
{
  while (isWSpace ())
    nextch ();
}

void
SAXParserP::scanString (const char *str)
{
  if (str == NULL || *str == '\0')
    return;
  for (;;)
    {
      if (curch == CH_EOF)
	break;
      else if (curch == *str)
	{
	  const char *p = str;
	  for (;;)
	    {
	      p += 1;
	      nextch ();
	      if (*p == '\0')
		return;
	      if (curch != *p)
		break;
	    }
	}
      nextch ();
    }
}

char *
SAXParserP::parseName ()
{
  StringBuilder *name = new StringBuilder ();

  if ((curch >= 'A' && curch <= 'Z') || (curch >= 'a' && curch <= 'z'))
    {
      name->append ((char) curch);
      nextch ();
      while (isalnum (curch) != 0 || curch == '_')
	{
	  name->append ((char) curch);
	  nextch ();
	}
    }

  char *res = name->toString ();
  delete name;
  return res;
}

/**
 * Replaces encoded XML characters with original characters
 * Attention: this method reuses the same string that is passed as the argument
 * @param str
 * @return str
 */
char *
SAXParserP::decodeString (char * str)
{
  // Check if string has %22% and replace it with double quotes
  // Also replace all other special combinations.
  char *from = str;
  char *to = str;
  if (strstr (from, "%") || strstr (from, "&"))
    {
      int len = strlen (from);
      for (int i = 0; i < len; i++)
	{
	  int nch = from[i];
	  // Process &...; combinations
	  if (nch == '&' && i + 3 < len)
	    {
	      if (from[i + 2] == 't' && from[i + 3] == ';')
		{
		  // check &lt; &gt;
		  if (from[i + 1] == 'l')
		    {
		      nch = '<';
		      i += 3;
		    }
		  else if (from[i + 1] == 'g')
		    {
		      nch = '>';
		      i += 3;
		    }
		}
	      else if (i + 4 < len && from[i + 4] == ';')
		{
		  // check &amp;
		  if (from[i + 1] == 'a' && from[i + 2] == 'm' && from[i + 3] == 'p')
		    {
		      nch = '&';
		      i += 4;
		    }
		}
	      else if ((i + 5 < len) && (from[i + 5] == ';'))
		{
		  // check &apos; &quot;
		  if (from[i + 1] == 'a' && from[i + 2] == 'p'
		      && from[i + 3] == 'o' && from[i + 4] == 's')
		    {
		      nch = '\'';
		      i += 5;
		    }
		  if (from[i + 1] == 'q' && from[i + 2] == 'u' && from[i + 3] == 'o' && from[i + 4] == 't')
		    {
		      nch = '"';
		      i += 5;
		    }
		}
	    }
	  // Process %XX% combinations
	  if (nch == '%' && i + 3 < len && from[i + 3] == '%')
	    {
	      int ch = hex (from[i + 1]);
	      if (ch >= 0)
		{
		  int ch2 = hex (from[i + 2]);
		  if (ch2 >= 0)
		    {
		      ch = ch * 16 + ch2;
		      nch = ch;
		      i += 3;
		    }
		}
	    }
	  *to++ = (char) nch;
	}
      *to = '\0';
    }
  return str;
}

char *
SAXParserP::parseString ()
{
  StringBuilder *str = new StringBuilder ();
  int quote = '>';
  if (curch == '"')
    {
      quote = curch;
      nextch ();
    }
  for (;;)
    {
      if (curch == CH_EOF)
	break;
      if (curch == quote)
	{
	  nextch ();
	  break;
	}
      str->append ((char) curch);
      nextch ();
    }

  char *res = str->toString ();
  // Decode XML characters
  res = decodeString (res);
  delete str;
  return res;
}

Attributes *
SAXParserP::parseAttributes ()
{
  AttributesP *attrs = new AttributesP ();

  for (;;)
    {
      skipWSpaces ();
      char *name = parseName ();
      if (name == NULL || *name == '\0')
	{
	  free (name);
	  break;
	}
      skipWSpaces ();
      if (curch != '=')
	{
	  SAXParseException *e = new SAXParseException (NULL, line, column);
	  dh->error (e);
	  scanString (">");
	  free (name);
	  return attrs;
	}
      nextch ();
      skipWSpaces ();
      char *value = parseString ();
      attrs->append (name, value);
    }
  return attrs;
}

void
SAXParserP::parseTag ()
{
  skipWSpaces ();
  bool empty = false;
  char *name = parseName ();
  if (name == NULL || *name == '\0')
    {
      SAXParseException *e = new SAXParseException (NULL, line, column);
      dh->error (e);
      scanString (">");
      free (name);
      return;
    }

  Attributes *attrs = parseAttributes ();
  if (curch == '/')
    {
      nextch ();
      empty = true;
    }
  if (curch == '>')
    nextch ();
  else
    {
      empty = false;
      SAXParseException *e = new SAXParseException (NULL, line, column);
      dh->error (e);
      scanString (">");
    }
  if (curch == CH_EOF)
    {
      free (name);
      delete attrs;
      return;
    }
  dh->startElement (NULL, NULL, name, attrs);
  if (empty)
    {
      dh->endElement (NULL, NULL, name);
      free (name);
      delete attrs;
      return;
    }

  StringBuilder *chars = new StringBuilder ();
  bool wspaces = true;
  for (;;)
    {
      if (curch == CH_EOF)
	break;
      else if (curch == '<')
	{
	  if (chars->length () > 0)
	    {
	      char *str = chars->toString ();
	      // Decode XML characters
	      str = decodeString (str);
	      if (wspaces)
		dh->ignorableWhitespace (str, 0, chars->length ());
	      else
		dh->characters (str, 0, chars->length ());
	      free (str);
	      chars->setLength (0);
	      wspaces = true;
	    }
	  nextch ();
	  if (curch == '/')
	    {
	      nextch ();
	      char *ename = parseName ();
	      if (ename && *ename != '\0')
		{
		  if (strcmp (name, ename) == 0)
		    {
		      skipWSpaces ();
		      if (curch == '>')
			{
			  nextch ();
			  dh->endElement (NULL, NULL, name);
			  free (ename);
			  break;
			}
		      SAXParseException *e = new SAXParseException (NULL, line, column);
		      dh->error (e);
		    }
		  else
		    {
		      SAXParseException *e = new SAXParseException (NULL, line, column);
		      dh->error (e);
		    }
		  scanString (">");
		}
	      free (ename);
	    }
	  else
	    parseTag ();
	}
      else
	{
	  if (!isWSpace ())
	    wspaces = false;
	  chars->append ((char) curch);
	  nextch ();
	}
    }

  free (name);
  delete attrs;
  delete chars;
  return;
}

void
SAXParserP::parseDocument ()
{
  dh->startDocument ();
  for (;;)
    {
      if (curch == CH_EOF)
	break;
      if (curch == '<')
	{
	  nextch ();
	  if (curch == '?')
	    scanString ("?>");
	  else if (curch == '!')
	    scanString (">");
	  else
	    parseTag ();
	}
      else
	nextch ();
    }
  dh->endDocument ();
}

/*
 *  Private implementation of SAXParserFactory
 */
class SAXParserFactoryP : public SAXParserFactory
{
public:
  SAXParserFactoryP () { }
  ~SAXParserFactoryP () { }
  SAXParser *newSAXParser ();

  void
  setFeature (const char *, bool) { }

  bool
  getFeature (const char *)
  {
    return false;
  }
};

SAXParser *
SAXParserFactoryP::newSAXParser ()
{
  return new SAXParserP ();
}

/*
 *  SAXParserFactory
 */
const char *SAXParserFactory::DEFAULT_PROPERTY_NAME = "javax.xml.parsers.SAXParserFactory";

SAXParserFactory *
SAXParserFactory::newInstance ()
{
  return new SAXParserFactoryP ();
}

void
DefaultHandler::dump_startElement (const char *qName, Attributes *attrs)
{
  fprintf (stderr, NTXT ("DefaultHandler::startElement qName='%s'\n"), STR (qName));
  for (int i = 0, sz = attrs ? attrs->getLength () : 0; i < sz; i++)
    {
      const char *qn = attrs->getQName (i);
      const char *vl = attrs->getValue (i);
      fprintf (stderr, NTXT ("  %d  '%s' = '%s'\n"), i, STR (qn), STR (vl));
    }
}
