/*
 * 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: jmaessen@google.com (Jan Maessen)
// Author: morlovich@google.com (Maksim Orlovich)

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

#include <cstddef>

#include "net/instaweb/rewriter/public/javascript_library_identification.h"
#include "pagespeed/kernel/base/message_handler.h"
#include "pagespeed/kernel/base/source_map.h"
#include "pagespeed/kernel/base/statistics.h"
#include "pagespeed/kernel/base/string.h"
#include "pagespeed/kernel/base/string_util.h"
#include "pagespeed/kernel/js/js_minify.h"
#include "pagespeed/kernel/js/js_tokenizer.h"

namespace net_instaweb {

// Statistics names
const char JavascriptRewriteConfig::kBlocksMinified[] =
    "javascript_blocks_minified";
const char JavascriptRewriteConfig::kLibrariesIdentified[] =
    "javascript_libraries_identified";
const char JavascriptRewriteConfig::kMinificationFailures[] =
    "javascript_minification_failures";
const char JavascriptRewriteConfig::kTotalBytesSaved[] =
    "javascript_total_bytes_saved";
const char JavascriptRewriteConfig::kTotalOriginalBytes[] =
    "javascript_total_original_bytes";
const char JavascriptRewriteConfig::kMinifyUses[] = "javascript_minify_uses";
const char JavascriptRewriteConfig::kNumReducingMinifications[] =
    "javascript_reducing_minifications";


const char JavascriptRewriteConfig::kJSMinificationDisabled[] =
    "javascript_minification_disabled";
const char JavascriptRewriteConfig::kJSDidNotShrink[] =
    "javascript_did_not_shrink";
const char JavascriptRewriteConfig::kJSFailedToWrite[] =
    "javascript_failed_to_write";

const char JavascriptCodeBlock::kIntrospectionComment[] =
    "This script contains introspective JavaScript and is unsafe to replace.";

JavascriptRewriteConfig::JavascriptRewriteConfig(
    Statistics* stats, bool minify, bool use_experimental_minifier,
    const JavascriptLibraryIdentification* identification,
    const pagespeed::js::JsTokenizerPatterns* js_tokenizer_patterns)
    : minify_(minify),
      use_experimental_minifier_(use_experimental_minifier),
      library_identification_(identification),
      js_tokenizer_patterns_(js_tokenizer_patterns),
      blocks_minified_(stats->GetVariable(kBlocksMinified)),
      libraries_identified_(stats->GetVariable(kLibrariesIdentified)),
      minification_failures_(stats->GetVariable(kMinificationFailures)),
      total_bytes_saved_(stats->GetVariable(kTotalBytesSaved)),
      total_original_bytes_(stats->GetVariable(kTotalOriginalBytes)),
      num_uses_(stats->GetVariable(kMinifyUses)),
      num_reducing_minifications_(
          stats->GetVariable(kNumReducingMinifications)),
      minification_disabled_(stats->GetVariable(kJSMinificationDisabled)),
      did_not_shrink_(stats->GetVariable(kJSDidNotShrink)),
      failed_to_write_(stats->GetVariable(kJSFailedToWrite)) {
}

void JavascriptRewriteConfig::InitStats(Statistics* statistics) {
  statistics->AddVariable(kBlocksMinified);
  statistics->AddVariable(kLibrariesIdentified);
  statistics->AddVariable(kMinificationFailures);
  statistics->AddVariable(kTotalBytesSaved);
  statistics->AddVariable(kTotalOriginalBytes);
  statistics->AddVariable(kMinifyUses);
  statistics->AddVariable(kNumReducingMinifications);

  statistics->AddVariable(kJSMinificationDisabled);
  statistics->AddVariable(kJSDidNotShrink);
  statistics->AddVariable(kJSFailedToWrite);
}

JavascriptCodeBlock::JavascriptCodeBlock(
    const StringPiece& original_code, JavascriptRewriteConfig* config,
    const StringPiece& message_id, MessageHandler* handler)
    : config_(config),
      message_id_(message_id.data(), message_id.size()),
      original_code_(original_code.data(), original_code.size()),
      rewritten_(false),
      successfully_rewritten_(false),
      handler_(handler) {
}

JavascriptCodeBlock::~JavascriptCodeBlock() { }

// Is this URL sanitary to be appended (in a line comment) to the JS doc?
bool JavascriptCodeBlock::IsSanitarySourceMapUrl(StringPiece url) {
  for (int i = 0, n = url.size(); i < n; ++i) {
    if (!IsNonControlAscii(url[i])) {
      // This is a bit broader than necessary. JS line comments can only be
      // terminated by Unicode line/paragraph separators (Zl/Zp). Instead of
      // searching for all of these, we simply check any non-standard chars.
      // Specifically, we reject any URL with control chars (0x00-0x1F,0x7F)
      // or any non-ASCII UTF-8 chars (Bytes 0x80-0xFF).
      // Because URLs passed in here are .pagespeed. rewritten URLs, we do
      // not expect any of them to be of this form anyway, so this case
      // shouldn't be hit.
      return false;
    }
  }
  return true;
}

void JavascriptCodeBlock::AppendSourceMapUrl(StringPiece url) {
  DCHECK(rewritten_);
  DCHECK(successfully_rewritten_);
  if (!IsSanitarySourceMapUrl(url)) {
    LOG(DFATAL) << "Unsanitary source map URL could not be added to JS " << url;
    return;
  }

  StrAppend(&rewritten_code_, "\n//# sourceMappingURL=", url, "\n");
}

StringPiece JavascriptCodeBlock::ComputeJavascriptLibrary() const {
  // TODO(jmaessen): when we compute minified version and find
  // a match, consider adding the un-minified hash to the library
  // identifier, and then using that to speed up identification
  // in future (at the cost of a double lookup for a miss).  Also
  // consider pruning candidate JS that is simply too small to match
  // a registered library.
  DCHECK(rewritten_);
  StringPiece result;
  if (rewritten_) {
    const JavascriptLibraryIdentification* library_identification =
        config_->library_identification();
    if (library_identification != NULL) {
      result = library_identification->Find(rewritten_code_);
      if (!result.empty()) {
        config_->libraries_identified()->Add(1);
      }
    }
  }
  return result;
}

bool JavascriptCodeBlock::UnsafeToRename(const StringPiece& script) {
  // If you're pulling out script elements it's probably because
  // you're trying to do a kind of reflection that would break if we
  // minified the code and mutated its url.
  return script.find("document.getElementsByTagName('script')")
           != StringPiece::npos ||
         script.find("document.getElementsByTagName(\"script\")")
           != StringPiece::npos ||
         script.find("$('script')")  // jquery version
           != StringPiece::npos ||
         script.find("$(\"script\")")
           != StringPiece::npos;
}

bool JavascriptCodeBlock::Rewrite() {
  DCHECK(!rewritten_);
  if (rewritten_) {
    return successfully_rewritten_;
  }

  rewritten_ = true;
  successfully_rewritten_ = false;
  // We minify for two reasons: because the user wants minified js code (in
  // which case output_code_ should point to the minified code when we're
  // done), or because we're trying to identify a javascript library.
  // Bail if we're not doing one of these things.
  if (!config_->minify() && (config_->library_identification() == NULL)) {
    return successfully_rewritten_;
  }

  if (MinifyJs(original_code_, &rewritten_code_, &source_mappings_)) {
    // Minification succeeded. The fact that it succeeded doesn't imply that
    // it actually saved anything; we increment num_reducing_uses when there
    // were actual savings.
    config_->blocks_minified()->Add(1);
    if (config_->minify() && rewritten_code_.size() < original_code_.size()) {
      // Minification will actually be used.
      successfully_rewritten_ = true;
      config_->num_reducing_uses()->Add(1);
      config_->total_original_bytes()->Add(original_code_.size());
      // Note: This unsigned arithmetic is guaranteed not to underflow because
      // of the if statement above.
      config_->total_bytes_saved()->Add(
          original_code_.size() - rewritten_code_.size());
    }
  } else {  // Minification failed.
    handler_->Message(kInfo, "%s: Javascript minification failed.  "
                      "Preserving old code.", message_id_.c_str());
    // Note: Although we set rewritten_code_, we do not consider this a
    // successful rewrite and thus will not minify. This is only used for
    // canonical library identification.
    TrimWhitespace(original_code_, &rewritten_code_);
    // Update stats.
    config_->minification_failures()->Add(1);
  }
  return successfully_rewritten_;
}

void JavascriptCodeBlock::SwapRewrittenString(GoogleString* other) {
  DCHECK(rewritten_);
  DCHECK(successfully_rewritten_);

  other->swap(rewritten_code_);

  rewritten_code_.clear();
  rewritten_ = false;
  successfully_rewritten_ = false;
}

bool JavascriptCodeBlock::MinifyJs(
    StringPiece input, GoogleString* output,
    source_map::MappingVector* source_mappings) {
  if (config_->use_experimental_minifier()) {
    return pagespeed::js::MinifyUtf8JsWithSourceMap(
        config_->js_tokenizer_patterns(), input, output, source_mappings);
  } else {
    return pagespeed::js::MinifyJs(input, output);
  }
}

}  // namespace net_instaweb
