// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

#include "vm/coverage.h"

#include "include/dart_api.h"

#include "vm/compiler.h"
#include "vm/isolate.h"
#include "vm/json_stream.h"
#include "vm/longjump.h"
#include "vm/object.h"
#include "vm/object_store.h"

namespace dart {

DEFINE_FLAG(charp, coverage_dir, NULL,
            "Enable writing coverage data into specified directory.");


class CoverageFilterAll : public CoverageFilter {
 public:
  bool ShouldOutputCoverageFor(const Library& lib,
                               const Script& script,
                               const Class& cls,
                               const Function& func) const {
    return true;
  }
};


// map[token_pos] -> line-number.
static void ComputeTokenPosToLineNumberMap(const Script& script,
                                           GrowableArray<intptr_t>* map) {
  const TokenStream& tkns = TokenStream::Handle(script.tokens());
  const intptr_t len = ExternalTypedData::Handle(tkns.GetStream()).Length();
  map->SetLength(len);
#if defined(DEBUG)
  for (intptr_t i = 0; i < len; i++) {
    (*map)[i] = -1;
  }
#endif
  TokenStream::Iterator tkit(tkns, 0, TokenStream::Iterator::kAllTokens);
  intptr_t cur_line = script.line_offset() + 1;
  while (tkit.CurrentTokenKind() != Token::kEOS) {
    (*map)[tkit.CurrentPosition()] = cur_line;
    if (tkit.CurrentTokenKind() == Token::kNEWLINE) {
      cur_line++;
    }
    tkit.Advance();
  }
}


void CodeCoverage::CompileAndAdd(const Function& function,
                                 const JSONArray& hits_or_sites,
                                 const GrowableArray<intptr_t>& pos_to_line,
                                 bool as_call_sites) {
  // If the function should not be compiled for coverage analysis, then just
  // skip this method.
  // TODO(iposva): Maybe we should skip synthesized methods in general too.
  if (function.is_abstract() || function.IsRedirectingFactory()) {
    return;
  }
  if (function.IsNonImplicitClosureFunction() &&
      (function.context_scope() == ContextScope::null())) {
    // TODO(iposva): This can arise if we attempt to compile an inner function
    // before we have compiled its enclosing function or if the enclosing
    // function failed to compile.
    return;
  }
  Thread* thread = Thread::Current();
  Zone* zone = thread->zone();
  // Make sure we have the unoptimized code for this function available.
  if (Compiler::EnsureUnoptimizedCode(thread, function) != Error::null()) {
    // Ignore the error and this function entirely.
    return;
  }
  const Code& code = Code::Handle(zone, function.unoptimized_code());
  ASSERT(!code.IsNull());

  // Print the hit counts for all IC datas.
  ZoneGrowableArray<const ICData*>* ic_data_array =
      new(zone) ZoneGrowableArray<const ICData*>();
  function.RestoreICDataMap(ic_data_array);
  const PcDescriptors& descriptors = PcDescriptors::Handle(
      zone, code.pc_descriptors());

  const intptr_t begin_pos = function.token_pos();
  const intptr_t end_pos = function.end_token_pos();
  intptr_t last_line = -1;
  intptr_t last_count = 0;
  // Only IC based calls have counting.
  PcDescriptors::Iterator iter(descriptors,
      RawPcDescriptors::kIcCall | RawPcDescriptors::kUnoptStaticCall);
  while (iter.MoveNext()) {
    HANDLESCOPE(thread);
    const ICData* ic_data = (*ic_data_array)[iter.DeoptId()];
    if (!ic_data->IsNull()) {
      const intptr_t token_pos = iter.TokenPos();
      // Filter out descriptors that do not map to tokens in the source code.
      if ((token_pos < begin_pos) || (token_pos > end_pos)) {
        continue;
      }
      if (as_call_sites) {
        bool is_static_call = iter.Kind() == RawPcDescriptors::kUnoptStaticCall;
        ic_data->PrintToJSONArray(hits_or_sites, token_pos, is_static_call);
      } else {
        intptr_t line = pos_to_line[token_pos];
#if defined(DEBUG)
        const Script& script = Script::Handle(zone, function.script());
        intptr_t test_line = -1;
        script.GetTokenLocation(token_pos, &test_line, NULL);
        ASSERT(test_line == line);
#endif
        // Merge hit data where possible.
        if (last_line == line) {
          last_count += ic_data->AggregateCount();
        } else {
          if ((last_line != -1)) {
            hits_or_sites.AddValue(last_line);
            hits_or_sites.AddValue(last_count);
          }
          last_count = ic_data->AggregateCount();
          last_line = line;
        }
      }
    }
  }
  // Write last hit value if needed.
  if (!as_call_sites && (last_line != -1)) {
    hits_or_sites.AddValue(last_line);
    hits_or_sites.AddValue(last_count);
  }
}


void CodeCoverage::PrintClass(const Library& lib,
                              const Class& cls,
                              const JSONArray& jsarr,
                              CoverageFilter* filter,
                              bool as_call_sites) {
  Thread* thread = Thread::Current();
  Isolate* isolate = thread->isolate();
  if (cls.EnsureIsFinalized(isolate) != Error::null()) {
    // Only classes that have been finalized do have a meaningful list of
    // functions.
    return;
  }
  Array& functions = Array::Handle(cls.functions());
  ASSERT(!functions.IsNull());
  Function& function = Function::Handle();
  Script& script = Script::Handle();
  String& saved_url = String::Handle();
  String& url = String::Handle();
  GrowableArray<intptr_t> pos_to_line;
  int i = 0;
  while (i < functions.Length()) {
    HANDLESCOPE(thread);
    function ^= functions.At(i);
    script = function.script();
    saved_url = script.url();
    if (!filter->ShouldOutputCoverageFor(lib, script, cls, function)) {
      i++;
      continue;
    }
    if (!as_call_sites) {
      ComputeTokenPosToLineNumberMap(script, &pos_to_line);
    }
    JSONObject jsobj(&jsarr);
    jsobj.AddProperty("source", saved_url.ToCString());
    jsobj.AddProperty("script", script);
    JSONArray hits_or_sites(&jsobj, as_call_sites ? "callSites" : "hits");

    // We stay within this loop while we are seeing functions from the same
    // source URI.
    while (i < functions.Length()) {
      function ^= functions.At(i);
      script = function.script();
      url = script.url();
      if (!url.Equals(saved_url)) {
        pos_to_line.Clear();
        break;
      }
      if (!filter->ShouldOutputCoverageFor(lib, script, cls, function)) {
        i++;
        continue;
      }
      CompileAndAdd(function, hits_or_sites, pos_to_line, as_call_sites);
      i++;
    }
  }

  GrowableObjectArray& closures =
      GrowableObjectArray::Handle(cls.closures());
  if (!closures.IsNull()) {
    i = 0;
    pos_to_line.Clear();
    // We need to keep rechecking the length of the closures array, as handling
    // a closure potentially adds new entries to the end.
    while (i < closures.Length()) {
      HANDLESCOPE(thread);
      function ^= closures.At(i);
      script = function.script();
      saved_url = script.url();
      if (!filter->ShouldOutputCoverageFor(lib, script, cls, function)) {
        i++;
        continue;
      }
      ComputeTokenPosToLineNumberMap(script, &pos_to_line);
      JSONObject jsobj(&jsarr);
      jsobj.AddProperty("source", saved_url.ToCString());
      jsobj.AddProperty("script", script);
      JSONArray hits_or_sites(&jsobj, as_call_sites ? "callSites" : "hits");

      // We stay within this loop while we are seeing functions from the same
      // source URI.
      while (i < closures.Length()) {
        function ^= closures.At(i);
        script = function.script();
        url = script.url();
        if (!url.Equals(saved_url)) {
          pos_to_line.Clear();
          break;
        }
        CompileAndAdd(function, hits_or_sites, pos_to_line, as_call_sites);
        i++;
      }
    }
  }
}


void CodeCoverage::Write(Isolate* isolate) {
  if (FLAG_coverage_dir == NULL) {
    return;
  }

  Dart_FileOpenCallback file_open = Isolate::file_open_callback();
  Dart_FileWriteCallback file_write = Isolate::file_write_callback();
  Dart_FileCloseCallback file_close = Isolate::file_close_callback();
  if ((file_open == NULL) || (file_write == NULL) || (file_close == NULL)) {
    return;
  }

  JSONStream stream;
  PrintJSON(isolate, &stream, NULL, false);

  intptr_t pid = OS::ProcessId();
  char* filename = OS::SCreate(Thread::Current()->zone(),
      "%s/dart-cov-%" Pd "-%" Pd64 ".json",
      FLAG_coverage_dir, pid, isolate->main_port());
  void* file = (*file_open)(filename, true);
  if (file == NULL) {
    OS::Print("Failed to write coverage file: %s\n", filename);
    return;
  }
  (*file_write)(stream.buffer()->buf(), stream.buffer()->length(), file);
  (*file_close)(file);
}


void CodeCoverage::PrintJSON(Isolate* isolate,
                             JSONStream* stream,
                             CoverageFilter* filter,
                             bool as_call_sites) {
  CoverageFilterAll default_filter;
  if (filter == NULL) {
    filter = &default_filter;
  }
  const GrowableObjectArray& libs = GrowableObjectArray::Handle(
      isolate, isolate->object_store()->libraries());
  Library& lib = Library::Handle();
  Class& cls = Class::Handle();
  JSONObject coverage(stream);
  coverage.AddProperty("type", "CodeCoverage");
  {
    JSONArray jsarr(&coverage, "coverage");
    for (int i = 0; i < libs.Length(); i++) {
      lib ^= libs.At(i);
      ClassDictionaryIterator it(lib, ClassDictionaryIterator::kIteratePrivate);
      while (it.HasNext()) {
        cls = it.GetNextClass();
        ASSERT(!cls.IsNull());
        PrintClass(lib, cls, jsarr, filter, as_call_sites);
      }
    }
  }
}


}  // namespace dart
