/*
 * Copyright 2011 Google Inc.
 *
 * 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.
 */

// Author: sligocki@google.com (Shawn Ligocki)

#include "net/instaweb/rewriter/public/css_minify.h"

#include "pagespeed/kernel/base/google_message_handler.h"
#include "pagespeed/kernel/base/gtest.h"
#include "pagespeed/kernel/base/scoped_ptr.h"
#include "pagespeed/kernel/base/string.h"
#include "pagespeed/kernel/base/string_writer.h"
#include "webutil/css/parser.h"


namespace net_instaweb {

namespace {

class CssMinifyTest : public ::testing::Test {
 protected:
  CssMinifyTest() {}
  virtual ~CssMinifyTest() {}

  void RewriteCss(const StringPiece& in_text, GoogleString* out_text) {
    out_text->clear();

    // Parse CSS.
    Css::Parser parser(in_text);
    parser.set_preservation_mode(true);
    parser.set_quirks_mode(false);
    scoped_ptr<Css::Stylesheet> stylesheet(parser.ParseRawStylesheet());

    if (parser.errors_seen_mask() != Css::Parser::kNoError) {
      in_text.CopyToString(out_text);
      return;
    }

    // Re-serialize
    StringWriter out_writer(out_text);
    EXPECT_TRUE(CssMinify::Stylesheet(*stylesheet, &out_writer, &handler_));
  }

  GoogleMessageHandler handler_;
};


TEST_F(CssMinifyTest, RewriteCssIncompleteUnicode) {
  // Test that a css string with an incomplete unicode character doesn't hang.
  // This string should not get minified either due to the error in it.
  static const unsigned char kCssStringData[] = {
      64, 109, 101, 100, 105, 97,  32,  40, 106,
      97, 120, 45,  119, 105, 100, 116, 104, 58,
      32, 88,  200, 194, 143, 135, 41,  32, 0};
  const char* css_string(reinterpret_cast<const char*>(kCssStringData));
  // This string is `echo "QG1lZGlhIChqYXgtd2lkdGg6IFjIwo+HKSA=" |base64 -d`
  GoogleString rewritten;
  RewriteCss(css_string, &rewritten);
  EXPECT_STREQ(rewritten, css_string) << "Should not hang";
}

TEST_F(CssMinifyTest, MinifyStylesheeetCollectingUrls) {
  const char kCss[] =
      ".a {\n"
      "  background-color: darkgreen;\n"
      "  background-image: url(foo.png);\n"
      "}";
  GoogleString minified;
  StringWriter writer(&minified);
  StringVector urls;
  CssMinify minify(&writer, &handler_);
  minify.set_url_collector(&urls);
  EXPECT_TRUE(minify.ParseStylesheet(kCss));
  ASSERT_EQ(1, urls.size());
  EXPECT_STREQ("foo.png", urls[0]);
  EXPECT_STREQ(".a{background-color:#006400;background-image:url(foo.png)}",
               minified);
}

TEST_F(CssMinifyTest, MinifyImportStylesheeetCollectingUrls) {
  const char kCss[] = "@import   'foo.png';";
  GoogleString minified;
  StringWriter writer(&minified);
  StringVector urls;
  CssMinify minify(&writer, &handler_);
  minify.set_url_collector(&urls);
  EXPECT_TRUE(minify.ParseStylesheet(kCss));
  ASSERT_EQ(1, urls.size());
  EXPECT_STREQ("foo.png", urls[0]);
  EXPECT_STREQ("@import url(foo.png);", minified);
}

TEST_F(CssMinifyTest, MinifyInvalid) {
  const char kCss[] = "{";
  GoogleString minified;
  StringWriter writer(&minified);
  CssMinify minify(&writer, &handler_);
  EXPECT_FALSE(minify.ParseStylesheet(kCss));
}

TEST_F(CssMinifyTest, DoNotFixBadColorsOrUnits) {
  const char kCss[] =
      ".a {\n"
      "  width: 10;\n"
      "  height: 20px;;\n"
      "  background-color: 0f0f0f;\n"
      "  foreground-color: #f0f0f0;\n"
      "}";
  GoogleString minified;
  StringWriter writer(&minified);
  CssMinify minify(&writer, &handler_);
  EXPECT_TRUE(minify.ParseStylesheet(kCss));

  // Note that we don't "fix" the '10' by appending a 'px', or the
  // background-color by adding a '#'.  In quirks-mode we would add the #.
  EXPECT_STREQ(
      ".a{width:10;height:20px;"
      "background-color: 0f0f0f;"  // Missing # not added, space is not removed.
      "foreground-color:#f0f0f0}",
      minified);
}

TEST_F(CssMinifyTest, RemoveZeroLengthButNotTimeOrPercentSuffix) {
  const char kCss[] =
      ".a {\n"
      "  width: 0px;\n"
      "  height: 0%;\n"
      "  -moz-transition-delay: 0s, 0s;\n"
      "}";
  GoogleString minified;
  StringWriter writer(&minified);
  CssMinify minify(&writer, &handler_);
  EXPECT_TRUE(minify.ParseStylesheet(kCss));
  // TODO(jmarantz): this CSS is not well minified.  We should strip
  // the spaces around the comma.
  EXPECT_STREQ(".a{width:0;height:0%;-moz-transition-delay:0s , 0s}", minified);
}

TEST_F(CssMinifyTest, ParsingAndMinifyingBackgroundAndFont) {
  const char kCss[] =
      ".a {\n"
      "  font:normal 16px Foo, sans-serif;\n"
      "}\n"
      "body {\n"
      "  background: #fff;\n"
      "}";
  Css::Parser parser(kCss);
  std::unique_ptr<Css::Stylesheet> stylesheet(parser.ParseStylesheet());
  GoogleString minified;
  StringWriter writer(&minified);

  EXPECT_TRUE(CssMinify::Stylesheet(*stylesheet, &writer, &handler_));
  // TODO(peleyal): We are adding more data than required. Should be:
  // ".a{font:normal 16px Foo,sans-serif}"
  // "body{background:#fff}"
  EXPECT_STREQ(
      ".a{font:16px Foo,sans-serif;font-style:normal;font-variant:normal;"
      "font-weight:normal;font-size:16px;line-height:normal;"
      "font-family:Foo,sans-serif}"
      "body{background:#fff;background-color:#fff;background-image:none;"
      "background-repeat:repeat;background-attachment:scroll;"
      "background-position-x:0%;background-position-y:0%}",
      minified);
}

TEST_F(CssMinifyTest, ParsingAndMinifingViewportUnits) {
  const char kCss[] =
      ".a {\n"
      "  margin-top: 70vh;\n"
      "  margin-bottom: 20vw;\n"
      "}\n";

  Css::Parser parser(kCss);
  std::unique_ptr<Css::Stylesheet> stylesheet(parser.ParseStylesheet());
  GoogleString minified;
  StringWriter writer(&minified);

  EXPECT_TRUE(CssMinify::Stylesheet(*stylesheet, &writer, &handler_));
  EXPECT_STREQ(".a{margin-top:70vh;margin-bottom:20vw}", minified);
}

TEST_F(CssMinifyTest, StraySingleQuote1) {
  static const char kCss[] =
      ".view_all a{\n"
      "  display: block;\n"
      "  'width: 100%;\n"
      "  padding: 5px 0 1px 0"
      "}";

  Css::Parser parser(kCss);
  std::unique_ptr<Css::Stylesheet> stylesheet(parser.ParseStylesheet());
  GoogleString minified;
  StringWriter writer(&minified);

  EXPECT_TRUE(CssMinify::Stylesheet(*stylesheet, &writer, &handler_));
  // There are two bits of error recovery happening here:
  // 1) error recovery for the unclosed 'width string eats all the way until
  //    the end of line.
  // 2) error recovery for the declaration starting with 'width eats all the way
  //    until the next semicolon or a closing } (skipping matching ones before)
  // --- which is after the padding declaration, since the first semicolon is
  // just a part of the 'width... string
  EXPECT_STREQ(".view_all a{display:block}", minified);
}

TEST_F(CssMinifyTest, StraySingleQuote2) {
  static const char kCss[] =
      ".view_all a{\n"
      "  display: block;\n"
      "  'width: 100%;\n"
      "  padding: 5px 0 1px 0;"
      "}";

  GoogleString minified;
  StringWriter writer(&minified);
  CssMinify minify(&writer, &handler_);
  StringVector urls;
  minify.set_url_collector(&urls);
  ASSERT_TRUE(minify.ParseStylesheet(kCss));
  EXPECT_STREQ(".view_all a{display:block;'width: 100%;\n"
               "  padding: 5px 0 1px 0}",
               minified);
}

TEST_F(CssMinifyTest, StraySingleQuote3) {
  // Non-permissive mode, should drop anything on the 'width line till \n,
  // and then continue recovery until the next semicolon.
  static const char kCss[] =
      ".view_all a{\n"
      "  display: block;\n"
      "  'width: 100%; border:1px solid red;\n"
      "  padding: 5px 0 1px 0;"
      "  margin: 1px;"
      "}";

  Css::Parser parser(kCss);
  std::unique_ptr<Css::Stylesheet> stylesheet(parser.ParseStylesheet());
  GoogleString minified;
  StringWriter writer(&minified);

  EXPECT_TRUE(CssMinify::Stylesheet(*stylesheet, &writer, &handler_));
  EXPECT_STREQ(".view_all a{display:block;margin:1px}", minified);
}

// checking whether unit is retained for zero value in calc function
TEST_F(CssMinifyTest, CalcFunctionWithZeroValueAndUnit) {
  static const char kCss[] =
      "@font-face {\n"
      " width: calc(600px - 0px)"
      "}";

  GoogleString minified;
  StringWriter writer(&minified);
  CssMinify minify(&writer, &handler_);

  EXPECT_TRUE(minify.ParseStylesheet(kCss));
  EXPECT_HAS_SUBSTR("width:calc(600px - 0px)", minified);
}

// checking unicode-range descriptor minification
TEST_F(CssMinifyTest, CssUnicodeRangeDescriptor) {
  static const char kCss[] =
      "@font-face {\n"
      " unicode-range: U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116;\n"
      "}";

  GoogleString minified;
  StringWriter writer(&minified);
  CssMinify minify(&writer, &handler_);

  EXPECT_TRUE(minify.ParseStylesheet(kCss));
  EXPECT_HAS_SUBSTR("unicode-range:U+0400-045F,U+0490-0491,U+04B0-04B1,U+2116",
      minified);
}

}  // namespace
}  // namespace net_instaweb
