/*
 * libjingle
 * Copyright 2004, Google Inc.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *
 *  1. Redistributions of source code must retain the above copyright notice,
 *     this list of conditions and the following disclaimer.
 *  2. Redistributions in binary form must reproduce the above copyright notice,
 *     this list of conditions and the following disclaimer in the documentation
 *     and/or other materials provided with the distribution.
 *  3. The name of the author may not be used to endorse or promote products
 *     derived from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
 * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

#include <string>
#include <sstream>
#include <iostream>
#include "talk/base/common.h"
#include "talk/base/gunit.h"
#include "talk/base/thread.h"
#include "talk/xmllite/xmlelement.h"

using buzz::QName;
using buzz::XmlAttr;
using buzz::XmlChild;
using buzz::XmlElement;

std::ostream& operator<<(std::ostream& os, const QName& name) {
  os << name.Namespace() << ":" << name.LocalPart();
  return os;
}

TEST(XmlElementTest, TestConstructors) {
  XmlElement elt(QName("google:test", "first"));
  EXPECT_EQ("<test:first xmlns:test=\"google:test\"/>", elt.Str());

  XmlElement elt2(QName("google:test", "first"), true);
  EXPECT_EQ("<first xmlns=\"google:test\"/>", elt2.Str());
}

TEST(XmlElementTest, TestAdd) {
  XmlElement elt(QName("google:test", "root"), true);
  elt.AddElement(new XmlElement(QName("google:test", "first")));
  elt.AddElement(new XmlElement(QName("google:test", "nested")), 1);
  elt.AddText("nested-value", 2);
  elt.AddText("between-", 1);
  elt.AddText("value", 1);
  elt.AddElement(new XmlElement(QName("google:test", "nested2")), 1);
  elt.AddElement(new XmlElement(QName("google:test", "second")));
  elt.AddText("init-value", 1);
  elt.AddElement(new XmlElement(QName("google:test", "nested3")), 1);
  elt.AddText("trailing-value", 1);

  // make sure it looks ok overall
  EXPECT_EQ("<root xmlns=\"google:test\">"
        "<first><nested>nested-value</nested>between-value<nested2/></first>"
        "<second>init-value<nested3/>trailing-value</second></root>",
        elt.Str());

  // make sure text was concatenated
  XmlChild * pchild =
    elt.FirstChild()->AsElement()->FirstChild()->NextChild();
  EXPECT_TRUE(pchild->IsText());
  EXPECT_EQ("between-value", pchild->AsText()->Text());
}

TEST(XmlElementTest, TestAttrs) {
  XmlElement elt(QName("", "root"));
  elt.SetAttr(QName("", "a"), "avalue");
  EXPECT_EQ("<root a=\"avalue\"/>", elt.Str());

  elt.SetAttr(QName("", "b"), "bvalue");
  EXPECT_EQ("<root a=\"avalue\" b=\"bvalue\"/>", elt.Str());

  elt.SetAttr(QName("", "a"), "avalue2");
  EXPECT_EQ("<root a=\"avalue2\" b=\"bvalue\"/>", elt.Str());

  elt.SetAttr(QName("", "b"), "bvalue2");
  EXPECT_EQ("<root a=\"avalue2\" b=\"bvalue2\"/>", elt.Str());

  elt.SetAttr(QName("", "c"), "cvalue");
  EXPECT_EQ("<root a=\"avalue2\" b=\"bvalue2\" c=\"cvalue\"/>", elt.Str());

  XmlAttr * patt = elt.FirstAttr();
  EXPECT_EQ(QName("", "a"), patt->Name());
  EXPECT_EQ("avalue2", patt->Value());

  patt = patt->NextAttr();
  EXPECT_EQ(QName("", "b"), patt->Name());
  EXPECT_EQ("bvalue2", patt->Value());

  patt = patt->NextAttr();
  EXPECT_EQ(QName("", "c"), patt->Name());
  EXPECT_EQ("cvalue", patt->Value());

  patt = patt->NextAttr();
  EXPECT_TRUE(NULL == patt);

  EXPECT_TRUE(elt.HasAttr(QName("", "a")));
  EXPECT_TRUE(elt.HasAttr(QName("", "b")));
  EXPECT_TRUE(elt.HasAttr(QName("", "c")));
  EXPECT_FALSE(elt.HasAttr(QName("", "d")));

  elt.SetAttr(QName("", "d"), "dvalue");
  EXPECT_EQ("<root a=\"avalue2\" b=\"bvalue2\" c=\"cvalue\" d=\"dvalue\"/>",
      elt.Str());
  EXPECT_TRUE(elt.HasAttr(QName("", "d")));

  elt.ClearAttr(QName("", "z"));  // not found, no effect
  EXPECT_EQ("<root a=\"avalue2\" b=\"bvalue2\" c=\"cvalue\" d=\"dvalue\"/>",
      elt.Str());

  elt.ClearAttr(QName("", "b"));
  EXPECT_EQ("<root a=\"avalue2\" c=\"cvalue\" d=\"dvalue\"/>", elt.Str());

  elt.ClearAttr(QName("", "a"));
  EXPECT_EQ("<root c=\"cvalue\" d=\"dvalue\"/>", elt.Str());

  elt.ClearAttr(QName("", "d"));
  EXPECT_EQ("<root c=\"cvalue\"/>", elt.Str());

  elt.ClearAttr(QName("", "c"));
  EXPECT_EQ("<root/>", elt.Str());
}

TEST(XmlElementTest, TestBodyText) {
  XmlElement elt(QName("", "root"));
  EXPECT_EQ("", elt.BodyText());

  elt.AddText("body value text");

  EXPECT_EQ("body value text", elt.BodyText());

  elt.ClearChildren();
  elt.AddText("more value ");
  elt.AddText("text");

  EXPECT_EQ("more value text", elt.BodyText());

  elt.ClearChildren();
  elt.AddText("decoy");
  elt.AddElement(new XmlElement(QName("", "dummy")));
  EXPECT_EQ("", elt.BodyText());

  elt.SetBodyText("replacement");
  EXPECT_EQ("replacement", elt.BodyText());

  elt.SetBodyText("");
  EXPECT_TRUE(NULL == elt.FirstChild());

  elt.SetBodyText("goodbye");
  EXPECT_EQ("goodbye", elt.FirstChild()->AsText()->Text());
  EXPECT_EQ("goodbye", elt.BodyText());
}

TEST(XmlElementTest, TestCopyConstructor) {
  XmlElement * element = XmlElement::ForStr(
      "<root xmlns='test-foo'>This is a <em a='avalue' b='bvalue'>"
      "little <b>little</b></em> test</root>");

  XmlElement * pelCopy = new XmlElement(*element);
  EXPECT_EQ("<root xmlns=\"test-foo\">This is a <em a=\"avalue\" b=\"bvalue\">"
      "little <b>little</b></em> test</root>", pelCopy->Str());
  delete pelCopy;

  pelCopy = new XmlElement(*(element->FirstChild()->NextChild()->AsElement()));
  EXPECT_EQ("<foo:em a=\"avalue\" b=\"bvalue\" xmlns:foo=\"test-foo\">"
      "little <foo:b>little</foo:b></foo:em>", pelCopy->Str());

  XmlAttr * patt = pelCopy->FirstAttr();
  EXPECT_EQ(QName("", "a"), patt->Name());
  EXPECT_EQ("avalue", patt->Value());

  patt = patt->NextAttr();
  EXPECT_EQ(QName("", "b"), patt->Name());
  EXPECT_EQ("bvalue", patt->Value());

  patt = patt->NextAttr();
  EXPECT_TRUE(NULL == patt);
  delete pelCopy;
  delete element;
}

TEST(XmlElementTest, TestNameSearch) {
  XmlElement * element = XmlElement::ForStr(
    "<root xmlns='test-foo'>"
      "<firstname>George</firstname>"
      "<middlename>X.</middlename>"
      "some text"
      "<lastname>Harrison</lastname>"
      "<firstname>John</firstname>"
      "<middlename>Y.</middlename>"
      "<lastname>Lennon</lastname>"
    "</root>");
  EXPECT_TRUE(NULL ==
      element->FirstNamed(QName("", "firstname")));
  EXPECT_EQ(element->FirstChild(),
      element->FirstNamed(QName("test-foo", "firstname")));
  EXPECT_EQ(element->FirstChild()->NextChild(),
      element->FirstNamed(QName("test-foo", "middlename")));
  EXPECT_EQ(element->FirstElement()->NextElement(),
      element->FirstNamed(QName("test-foo", "middlename")));
  EXPECT_EQ("Harrison",
      element->TextNamed(QName("test-foo", "lastname")));
  EXPECT_EQ(element->FirstElement()->NextElement()->NextElement(),
      element->FirstNamed(QName("test-foo", "lastname")));
  EXPECT_EQ("John", element->FirstNamed(QName("test-foo", "firstname"))->
      NextNamed(QName("test-foo", "firstname"))->BodyText());
  EXPECT_EQ("Y.", element->FirstNamed(QName("test-foo", "middlename"))->
      NextNamed(QName("test-foo", "middlename"))->BodyText());
  EXPECT_EQ("Lennon", element->FirstNamed(QName("test-foo", "lastname"))->
      NextNamed(QName("test-foo", "lastname"))->BodyText());
  EXPECT_TRUE(NULL == element->FirstNamed(QName("test-foo", "firstname"))->
      NextNamed(QName("test-foo", "firstname"))->
      NextNamed(QName("test-foo", "firstname")));

  delete element;
}

class XmlElementCreatorThread : public talk_base::Thread {
 public:
  XmlElementCreatorThread(int count, buzz::QName qname) :
      count_(count), qname_(qname) {}

  virtual void Run() {
    std::vector<buzz::XmlElement*> elems;
    for (int i = 0; i < count_; i++) {
      elems.push_back(new XmlElement(qname_));
    }
    for (int i = 0; i < count_; i++) {
      delete elems[i];
    }
  }

 private:
  int count_;
  buzz::QName qname_;
};

// If XmlElement creation and destruction isn't thread safe,
// this test should crash.
TEST(XmlElementTest, TestMultithread) {
  int thread_count = 2;  // Was 100, but that's too slow.
  int elem_count = 100;  // Was 100000, but that's too slow.
  buzz::QName qname("foo", "bar");

  std::vector<talk_base::Thread*> threads;
  for (int i = 0; i < thread_count; i++) {
    threads.push_back(
        new XmlElementCreatorThread(elem_count, qname));
    threads[i]->Start();
  }

  for (int i = 0; i < thread_count; i++) {
    threads[i]->Stop();
    delete threads[i];
  }
}
