/*
 * Copyright 2015 Google Inc. All Rights Reserved.
 *
 * Licensed 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.
 */

#include "base/memory/ref_counted.h"
#include "base/memory/scoped_ptr.h"
#include "cobalt/base/clock.h"
#include "cobalt/css_parser/parser.h"
#include "cobalt/dom/document.h"
#include "cobalt/dom/dom_parser.h"
#include "cobalt/dom/dom_stat_tracker.h"
#include "cobalt/dom/html_body_element.h"
#include "cobalt/dom/html_br_element.h"
#include "cobalt/dom/html_div_element.h"
#include "cobalt/dom/html_element_context.h"
#include "cobalt/dom/html_head_element.h"
#include "cobalt/dom/html_html_element.h"
#include "cobalt/dom/html_paragraph_element.h"
#include "cobalt/dom/text.h"
#include "cobalt/webdriver/algorithms.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"

namespace cobalt {
namespace webdriver {
namespace {
const char kBlankDocument[] = "<html><head/><body/><html>";
class GetElementTextTest : public ::testing::Test {
 protected:
  GetElementTextTest()
      : css_parser_(css_parser::Parser::Create()),
        dom_stat_tracker_(new dom::DomStatTracker("GetElementTextTest")),
        html_element_context_(NULL, css_parser_.get(), NULL, NULL, NULL, NULL,
                              NULL, NULL, NULL, NULL, NULL,
                              dom_stat_tracker_.get(), "") {}

  void SetUp() OVERRIDE {
    dom::Document::Options options;
    options.viewport_size = math::Size(1920, 1080);
    options.navigation_start_clock = new base::SystemMonotonicClock();
    document_ = new dom::Document(&html_element_context_, options);
    document_->AppendChild(new dom::HTMLHtmlElement(document_.get()));
    document_->html()->AppendChild(new dom::HTMLHeadElement(document_.get()));
    document_->html()->AppendChild(new dom::HTMLBodyElement(document_.get()));
    div_ = new dom::HTMLDivElement(document_.get());
    document_->body()->AppendChild(div_);

    document_->SampleTimelineTime();
  }

  void AppendText(const char* text_content) {
    div_->AppendChild(new dom::Text(document_.get(), text_content));
  }

  void AppendBR() {
    div_->AppendChild(new dom::HTMLBRElement(document_.get()));
  }

  void AppendParagraphWithDisplayStyle(const char* display_style) {
    scoped_refptr<dom::HTMLParagraphElement> p(
        new dom::HTMLParagraphElement(document_.get()));
    p->style()->set_display(display_style, NULL);
    div_->AppendChild(p);
  }

  scoped_ptr<css_parser::Parser> css_parser_;
  scoped_ptr<dom::DomStatTracker> dom_stat_tracker_;
  dom::HTMLElementContext html_element_context_;
  scoped_refptr<dom::Document> document_;
  scoped_refptr<dom::HTMLDivElement> div_;
};
}  // namespace

TEST_F(GetElementTextTest, ZeroSpaceWidthIsRemoved) {
  AppendText("a\u200bb\u200ec\u200fd");
  EXPECT_STREQ("abcd", algorithms::GetElementText(div_.get()).c_str());
}

TEST_F(GetElementTextTest, NewLinesAreConvertedToSpaces) {
  AppendText("a\r\nb\rc\nd");
  EXPECT_STREQ("a b c d", algorithms::GetElementText(div_.get()).c_str());
}

TEST_F(GetElementTextTest, NoWrapStyle) {
  div_->style()->set_white_space("nowrap", NULL);
  AppendText("a\n\nb\nc\td\u2028e\u2029f\xa0g");
  EXPECT_STREQ("a b c d e f g", algorithms::GetElementText(div_.get()).c_str());
}

TEST_F(GetElementTextTest, Uppercase) {
  div_->style()->set_text_transform("uppercase", NULL);
  AppendText("AbCdE fGhIj kl-mn-Op");
  EXPECT_STREQ("ABCDE FGHIJ KL-MN-OP",
               algorithms::GetElementText(div_.get()).c_str());
}

TEST_F(GetElementTextTest, BrElementBecomesNewLine) {
  AppendText("a");
  AppendBR();
  AppendText("b");
  AppendBR();
  AppendBR();
  AppendText("c");

  EXPECT_STREQ("a\nb\n\nc", algorithms::GetElementText(div_.get()).c_str());
}

TEST_F(GetElementTextTest, Blocks) {
  AppendText("a");
  AppendParagraphWithDisplayStyle("block");
  AppendText("b");
  AppendParagraphWithDisplayStyle("block");
  AppendParagraphWithDisplayStyle("block");
  AppendText("c");

  EXPECT_STREQ("a\nb\nc", algorithms::GetElementText(div_.get()).c_str());
}

}  // namespace webdriver
}  // namespace cobalt
