/*
 * Copyright 2010 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 <algorithm>
#include <vector>

#include "base/logging.h"
#include "pagespeed/kernel/base/message_handler.h"
#include "pagespeed/kernel/base/scoped_ptr.h"
#include "pagespeed/kernel/base/string.h"
#include "pagespeed/kernel/base/writer.h"
#include "util/utf8/public/unicodetext.h"
#include "webutil/css/identifier.h"
#include "webutil/css/media.h"
#include "webutil/css/parser.h"
#include "webutil/css/property.h"
#include "webutil/css/selector.h"
#include "webutil/css/tostring.h"
#include "webutil/css/value.h"
#include "webutil/html/htmlcolor.h"

namespace net_instaweb {

bool CssMinify::Stylesheet(const Css::Stylesheet& stylesheet,
                           Writer* writer,
                           MessageHandler* handler) {
  // Get an object to encapsulate writing.
  CssMinify minifier(writer, handler);
  minifier.Minify(stylesheet);
  return minifier.ok_;
}

bool CssMinify::ParseStylesheet(StringPiece stylesheet_text) {
  ok_ = true;
  Css::Parser parser(stylesheet_text);
  parser.set_preservation_mode(true);  // Leave in unparseable regions.
  parser.set_quirks_mode(false);  // Don't fix badly formatted colors.
  scoped_ptr<Css::Stylesheet> stylesheet(parser.ParseRawStylesheet());

  // Report error summary.
  if (error_writer_ != NULL) {
    if (parser.errors_seen_mask() != Css::Parser::kNoError) {
      error_writer_->Write(StringPrintf(
          "CSS parsing error mask %s\n",
          Integer64ToString(parser.errors_seen_mask()).c_str()), handler_);
    }
    if (parser.unparseable_sections_seen_mask() != Css::Parser::kNoError) {
      error_writer_->Write(StringPrintf(
          "CSS unparseable sections mask %s\n",
          Integer64ToString(parser.unparseable_sections_seen_mask()).c_str()),
                        handler_);
    }
    // Report individual errors.
    for (int i = 0, n = parser.errors_seen().size(); i < n; ++i) {
      Css::Parser::ErrorInfo error = parser.errors_seen()[i];
      error_writer_->Write(error.message, handler_);
      error_writer_->Write("\n", handler_);
    }
  }

  Minify(*stylesheet);
  return ok_ && (parser.errors_seen_mask() == Css::Parser::kNoError);
}

bool CssMinify::Declarations(const Css::Declarations& declarations,
                             Writer* writer,
                             MessageHandler* handler) {
  // Get an object to encapsulate writing.
  CssMinify minifier(writer, handler);
  minifier.JoinMinify(declarations, ";");
  return minifier.ok_;
}

CssMinify::CssMinify(Writer* writer, MessageHandler* handler)
    : writer_(writer), error_writer_(NULL), handler_(handler), ok_(true),
      url_collector_(NULL) {
}

CssMinify::~CssMinify() {
}

// Write if we have not encountered write error yet.
void CssMinify::Write(const StringPiece& str) {
  if (ok_) {
    ok_ &= writer_->Write(str, handler_);
  }
}

void CssMinify::WriteURL(const UnicodeText& url) {
  StringPiece string_url(url.utf8_data(), url.utf8_length());
  if (url_collector_ != NULL) {
    string_url.CopyToString(StringVectorAdd(url_collector_));
  }
  Write(Css::EscapeUrl(string_url));
}

// Write out minified version of each element of vector using supplied function
// seperated by sep.
template<typename Container>
void CssMinify::JoinMinify(const Container& container, const StringPiece& sep) {
  JoinMinifyIter(container.begin(), container.end(), sep);
}

template<typename Iterator>
void CssMinify::JoinMinifyIter(const Iterator& begin, const Iterator& end,
                               const StringPiece& sep) {
  for (Iterator iter = begin; iter != end; ++iter) {
    if (iter != begin) {
      Write(sep);
    }
    Minify(**iter);
  }
}

template<>
void CssMinify::JoinMinifyIter<Css::FontFaces::const_iterator>(
    const Css::FontFaces::const_iterator& begin,
    const Css::FontFaces::const_iterator& end,
    const StringPiece& sep) {
  // Go through the list of @font-faces finding the contiguous subsets with the
  // same set of media (f.ex [a b b b a a] -> [a] [b b b] [a a]). For each
  // such subset, emit the start of the @media rule (if required), then emit
  // each @font-face without an @media rule, separating them by the given 'sep',
  // then emit the end of the @media rule (if required).
  for (Css::FontFaces::const_iterator iter = begin; iter != end; ) {
    const Css::MediaQueries& first_media_queries = (*iter)->media_queries();
    MinifyMediaStart(first_media_queries);
    MinifyFontFaceIgnoringMedia(**iter);
    for (++iter; iter != end && Equals(first_media_queries,
                                       (*iter)->media_queries()); ++iter) {
      Write(sep);
      MinifyFontFaceIgnoringMedia(**iter);
    }
    MinifyMediaEnd(first_media_queries);
  }
}

template<>
void CssMinify::JoinMinifyIter<Css::Rulesets::const_iterator>(
    const Css::Rulesets::const_iterator& begin,
    const Css::Rulesets::const_iterator& end,
    const StringPiece& sep) {
  // Go through the list of rulesets finding the contiguous subsets with the
  // same set of media (f.ex [a b b b a a] -> [a] [b b b] [a a]). For each
  // such subset, emit the start of the @media rule (if required), then emit
  // each ruleset without an @media rule, separating them by the given 'sep',
  // then emit the end of the @media rule (if required).
  for (Css::Rulesets::const_iterator iter = begin; iter != end; ) {
    const Css::MediaQueries& first_media_queries = (*iter)->media_queries();
    MinifyMediaStart(first_media_queries);
    MinifyRulesetIgnoringMedia(**iter);
    for (++iter; iter != end && Equals(first_media_queries,
                                       (*iter)->media_queries()); ++iter) {
      Write(sep);
      MinifyRulesetIgnoringMedia(**iter);
    }
    MinifyMediaEnd(first_media_queries);
  }
}


// Write the minified versions of each type. Most of these are called via
// templated instantiations of JoinMinify (or JoinMinifyIter) so that we can
// abstract the idea of minifying all sub-elements of a vector and joining them
// together.
//   Adapted from webutil/css/tostring.cc

void CssMinify::Minify(const Css::Stylesheet& stylesheet) {
  // We might want to add in unnecessary newlines between rules and imports
  // so that some readability is preserved.
  Minify(stylesheet.charsets());
  JoinMinify(stylesheet.imports(), "");
  // Note: Adjacent @font-face with the same media type are placed in the same
  // @media block. The same is true for adjacent Ruelsets. However, we do not
  // yet combine @font-face with Rulesets into the same @media block because
  // we do not expect this to be worth the trouble.
  JoinMinify(stylesheet.font_faces(), "");
  JoinMinify(stylesheet.rulesets(), "");
}

void CssMinify::Minify(const Css::Charsets& charsets) {
  for (Css::Charsets::const_iterator iter = charsets.begin();
       iter != charsets.end(); ++iter) {
    Write("@charset \"");
    Write(Css::EscapeString(*iter));
    Write("\";");
  }
}

void CssMinify::Minify(const Css::Import& import) {
  Write("@import url(");
  WriteURL(import.link());
  Write(")");
  if (!import.media_queries().empty()) {
    Write(" ");
    JoinMinify(import.media_queries(), ",");
  }
  Write(";");
}

void CssMinify::Minify(const Css::MediaQuery& media_query) {
  switch (media_query.qualifier()) {
    case Css::MediaQuery::ONLY:
      Write("only ");
      break;
    case Css::MediaQuery::NOT:
      Write("not ");
      break;
    case Css::MediaQuery::NO_QUALIFIER:
      break;
  }

  Write(Css::EscapeIdentifier(media_query.media_type()));
  if (!media_query.media_type().empty() && !media_query.expressions().empty()) {
    Write(" and ");
  }
  JoinMinify(media_query.expressions(), " and ");
}

void CssMinify::Minify(const Css::MediaExpression& expression) {
  Write("(");
  Write(Css::EscapeIdentifier(expression.name()));
  if (expression.has_value()) {
    Write(":");
    const UnicodeText& value = expression.value();
    // Note: Value is an unparsed region of raw bytes. So don't escape it.
    Write(StringPiece(value.utf8_data(), value.utf8_length()));
  }
  Write(")");
}

void CssMinify::MinifyMediaStart(const Css::MediaQueries& media_queries) {
  if (!media_queries.empty()) {
    Write("@media ");
    JoinMinify(media_queries, ",");
    Write("{");
  }
}

void CssMinify::MinifyMediaEnd(const Css::MediaQueries& media_queries) {
  if (!media_queries.empty()) {
    Write("}");
  }
}

void CssMinify::MinifyFontFaceIgnoringMedia(const Css::FontFace& font_face) {
  Write("@font-face{");
  JoinMinify(font_face.declarations(), ";");
  Write("}");
}

void CssMinify::MinifyRulesetIgnoringMedia(const Css::Ruleset& ruleset) {
  // TODO(sligocki): Only write out ruleset if declarations() is non-empty.
  // Note that we should also propagate this up to not print @media rules
  // if all their rulesets are empty. Otherwise we'll fail the css_minify_test
  // which checks for idempotent minifications.
  switch (ruleset.type()) {
    case Css::Ruleset::RULESET:
      if (ruleset.selectors().is_dummy()) {
        Write(ruleset.selectors().bytes_in_original_buffer());
      } else {
        JoinMinify(ruleset.selectors(), ",");
      }
      Write("{");
      JoinMinify(ruleset.declarations(), ";");
      Write("}");
      break;
    case Css::Ruleset::UNPARSED_REGION:
      Minify(*ruleset.unparsed_region());
      break;
  }
}

void CssMinify::Minify(const Css::Selector& selector) {
  // Note Css::Selector == std::vector<Css::SimpleSelectors*>
  Css::Selector::const_iterator iter = selector.begin();
  if (iter != selector.end()) {
    bool isfirst = true;
    Minify(**iter, isfirst);
    ++iter;
    JoinMinifyIter(iter, selector.end(), "");
  }
}

void CssMinify::Minify(const Css::SimpleSelectors& sselectors, bool isfirst) {
  if (sselectors.combinator() == Css::SimpleSelectors::CHILD) {
    Write(">");
  } else if (sselectors.combinator() == Css::SimpleSelectors::SIBLING) {
    Write("+");
  } else if (!isfirst) {
    Write(" ");
  }
  // Note Css::SimpleSelectors == std::vector<Css::SimpleSelector*>
  JoinMinify(sselectors, "");
}

void CssMinify::Minify(const Css::SimpleSelector& sselector) {
  // SimpleSelector::ToString is already basically minified (and is escaped).
  Write(sselector.ToString());
}

namespace {

bool IsValueNormalIdentifier(const Css::Value& value) {
  return (value.GetLexicalUnitType() == Css::Value::IDENT &&
          value.GetIdentifier().ident() == Css::Identifier::NORMAL);
}

// See http://www.w3.org/TR/css3-values/#lengths : Lengths refer to
// distance measurements and are denoted by <length> in the property
// definitions. A length is a dimension. However, for zero lengths the
// unit identifier is optional (i.e. can be syntactically represented
// as the <number> 0).
//
// http://www.w3.org/TR/css3-values/#relative-lengths
// http://www.w3.org/TR/css3-values/#absolute-lengths
const char* kLengths[] = {
  "ch",
  "cm",
  "em",
  "ex",
  "in",
  "mm",
  "pc",
  "pt",
  "px",
  "q",
  "rem",
  "vh",
  "vmax",
  "vmin",
  "vw",
};

bool IsLength(const GoogleString& unit) {
  return std::binary_search(kLengths, kLengths + arraysize(kLengths),
                            unit);
}

bool UnitsRequiredForValueZero(const GoogleString& unit) {
  // https://github.com/pagespeed/mod_pagespeed/issues/1164 : Chrome does not
  // allow abbreviating 0s or 0% as 0.  It only allows that abbreviation for
  // lengths.
  //
  // https://github.com/pagespeed/mod_pagespeed/issues/1261  See
  // https://www.w3.org/TR/CSS2/visudet.html#the-height-property
  return (unit == "%") || !IsLength(unit);
}

}  // namespace

void CssMinify::MinifyFont(const Css::Values& font_values) {
  CHECK_LE(5U, font_values.size());

  // font-style: defaults to normal
  if (!IsValueNormalIdentifier(*font_values.get(0))) {
    Minify(*font_values.get(0));
    Write(" ");
  }
  // font-variant: defaults to normal
  if (!IsValueNormalIdentifier(*font_values.get(1))) {
    Minify(*font_values.get(1));
    Write(" ");
  }
  // font-weight: defaults to normal
  if (!IsValueNormalIdentifier(*font_values.get(2))) {
    Minify(*font_values.get(2));
    Write(" ");
  }
  // font-size is required
  Minify(*font_values.get(3));
  // line-height: defaults to normal
  if (!IsValueNormalIdentifier(*font_values.get(4))) {
    Write("/");
    Minify(*font_values.get(4));
  }
  // font-family:
  for (int i = 5, n = font_values.size(); i < n; ++i) {
    Write(i == 5 ? " " : ",");
    Minify(*font_values.get(i));
  }
}

void CssMinify::Minify(const Css::Declaration& declaration) {
  if (declaration.prop() == Css::Property::UNPARSEABLE) {
    Write(declaration.bytes_in_original_buffer());
  } else {
    Write(Css::EscapeIdentifier(declaration.prop_text()));
    Write(":");
    switch (declaration.prop()) {
      case Css::Property::FONT_FAMILY:
        JoinMinify(*declaration.values(), ",");
        break;
      case Css::Property::FONT:
        // font: menu special case.
        if (declaration.values()->size() == 1) {
          JoinMinify(*declaration.values(), " ");
          // Normal font notation.
        } else if (declaration.values()->size() >= 5) {
          MinifyFont(*declaration.values());
        } else {
          handler_->Message(kError, "Unexpected number of values in "
                            "font declaration: %d",
                            static_cast<int>(declaration.values()->size()));
          ok_ = false;
        }
        break;
      default:
        JoinMinify(*declaration.values(), " ");
        break;
    }
    if (declaration.IsImportant()) {
      Write("!important");
    }
  }
}

void CssMinify::Minify(const Css::Value& value) {
  switch (value.GetLexicalUnitType()) {
    case Css::Value::NUMBER: {
      GoogleString buffer;
      StringPiece number_string;
      if (!value.bytes_in_original_buffer().empty()) {
        // All parsed values should have verbatim bytes set and we use them
        // to ensure we keep the original precision.
        number_string = value.bytes_in_original_buffer();
      } else {
        // Values added or modified outside of the parsing code need
        // to be converted to strings by us.
        buffer = StringPrintf("%.16g", value.GetFloatValue());
        number_string = buffer;
      }
      if (number_string.starts_with("0.")) {
        // Optimization: Strip "0.25" -> ".25".
        Write(number_string.substr(1));
      } else if (number_string.starts_with("-0.")) {
        // Optimization: Strip "-0.25" -> "-.25".
        Write("-");
        Write(number_string.substr(2));
      } else {
        // Otherwise just print the original string.
        Write(number_string);
      }

      // Optimization: Do not print units if value is 0.
      GoogleString unit = value.GetDimensionUnitText();
      if (!unit.empty() &&
          ((value.GetFloatValue() != 0) || UnitsRequiredForValueZero(unit))) {
        // Unit can be either "%" or an identifier.
        if (unit != "%") {
          unit = Css::EscapeIdentifier(unit);
        }
        Write(unit);
      }
      break;
    }
    case Css::Value::URI:
      Write("url(");
      WriteURL(value.GetStringValue());
      Write(")");
      break;
    case Css::Value::FUNCTION:
      Write(Css::EscapeIdentifier(value.GetFunctionName()));
      Write("(");
      Minify(*value.GetParametersWithSeparators());
      Write(")");
      break;
    case Css::Value::RECT:
      Write("rect(");
      Minify(*value.GetParametersWithSeparators());
      Write(")");
      break;
    case Css::Value::COLOR:
      // TODO(sligocki): Can we assert, or might this happen in the wild?
      CHECK(value.GetColorValue().IsDefined());
      Write(HtmlColorUtils::MaybeConvertToCssShorthand(
          value.GetColorValue()));
      break;
    case Css::Value::STRING:
      if (!value.bytes_in_original_buffer().empty()) {
        // All parsed strings should have verbatim bytes set.
        // Note: bytes_in_original_buffer() contains quote chars.
        Write(value.bytes_in_original_buffer());
      } else {
        // Strings added or modified outside of the parsing code will need
        // to be serialized by us.
        Write("\"");
        Write(Css::EscapeString(value.GetStringValue()));
        Write("\"");
      }
      break;
    case Css::Value::IDENT:
      Write(Css::EscapeIdentifier(value.GetIdentifierText()));
      break;
    case Css::Value::COMMA:
      // TODO(sligocki): Do not add spaces around COMMA tokens.
      Write(",");
      break;
    case Css::Value::UNKNOWN:
      handler_->MessageS(kError, "Unknown attribute");
      ok_ = false;
      break;
    case Css::Value::DEFAULT:
      break;
  }
}

void CssMinify::Minify(const Css::FunctionParameters& parameters) {
  if (parameters.size() >= 1) {
    Minify(*parameters.value(0));
  }
  for (int i = 1, n = parameters.size(); i < n; ++i) {
    switch (parameters.separator(i)) {
      case Css::FunctionParameters::COMMA_SEPARATED:
        Write(",");
        break;
      case Css::FunctionParameters::SPACE_SEPARATED:
        Write(" ");
        break;
    }
    Minify(*parameters.value(i));
  }
}

void CssMinify::Minify(const Css::UnparsedRegion& unparsed_region) {
  Write(unparsed_region.bytes_in_original_buffer());
}


bool CssMinify::Equals(const Css::MediaQueries& a,
                       const Css::MediaQueries& b) const {
  if (a.size() != b.size()) {
    return false;
  }
  for (int i = 0, n = a.size(); i < n; ++i) {
    if (!Equals(*a.at(i), *b.at(i))) {
      return false;
    }
  }
  return true;
}

bool CssMinify::Equals(const Css::MediaQuery& a,
                       const Css::MediaQuery& b) const {
  if (a.qualifier() != b.qualifier() ||
      a.media_type() != b.media_type() ||
      a.expressions().size() != b.expressions().size()) {
    return false;
  }
  for (int i = 0, n = a.expressions().size(); i < n; ++i) {
    if (!Equals(a.expression(i), b.expression(i))) {
      return false;
    }
  }
  return true;
}

bool CssMinify::Equals(const Css::MediaExpression& a,
                       const Css::MediaExpression& b) const {
  if (a.name() != b.name() ||
      a.has_value() != b.has_value()) {
    return false;
  }
  if (a.has_value() && a.value() != b.value()) {
    return false;
  }
  return true;
}

}  // namespace net_instaweb
