// Copyright (c) 2015, 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.

#ifndef RUNTIME_VM_SOURCE_REPORT_H_
#define RUNTIME_VM_SOURCE_REPORT_H_

#include "vm/globals.h"
#if !defined(PRODUCT) && !defined(DART_PRECOMPILED_RUNTIME)

#include "vm/allocation.h"
#include "vm/flags.h"
#include "vm/hash_map.h"
#include "vm/object.h"
#include "vm/profiler_service.h"
#include "vm/token_position.h"

namespace dart {

// A SourceReport object is used to generate reports about the program
// source code, with information associated with source token
// positions.  There are multiple possible kinds of reports.
class SourceReport {
 public:
  enum ReportKind {
    kCallSites = 0x1,
    kCoverage = 0x2,
    kPossibleBreakpoints = 0x4,
    kProfile = 0x8,
    kBranchCoverage = 0x10,
  };

  static const char* kCallSitesStr;
  static const char* kCoverageStr;
  static const char* kPossibleBreakpointsStr;
  static const char* kProfileStr;
  static const char* kBranchCoverageStr;

  enum CompileMode { kNoCompile, kForceCompile };

  // report_set is a bitvector indicating which reports to generate
  // (e.g. kCallSites | kCoverage).
  //
  // If library_filters is not null, then the report will only include libraries
  // whose URIs start with one of the filter strings.
  explicit SourceReport(intptr_t report_set,
                        CompileMode compile = kNoCompile,
                        bool report_lines = false);
  explicit SourceReport(intptr_t report_set,
                        const GrowableObjectArray& library_filters,
                        CompileMode compile = kNoCompile,
                        bool report_lines = false);
  ~SourceReport();

  // Generate a source report for (some subrange of) a script.
  //
  // If script is null, then the report is generated for all scripts
  // in the isolate.
  void PrintJSON(JSONStream* js,
                 const Script& script,
                 TokenPosition start_pos = TokenPosition::kMinSource,
                 TokenPosition end_pos = TokenPosition::kMaxSource);

 private:
  void ClearScriptTable();
  void Init(Thread* thread,
            const Script* script,
            TokenPosition start_pos,
            TokenPosition end_pos);

  Thread* thread() const { return thread_; }
  Zone* zone() const { return thread_->zone(); }
  Isolate* isolate() const { return thread_->isolate(); }

  bool IsReportRequested(ReportKind report_kind);
  bool ShouldSkipFunction(const Function& func);
  bool ShouldSkipField(const Field& field);
  bool ShouldCoverageSkipCallSite(const ICData* ic_data);
  intptr_t GetScriptIndex(const Script& script, bool bypass_filters = false);
  bool ScriptIsLoadedByLibrary(const Script& script, const Library& lib);
  intptr_t GetTokenPosOrLine(const Script& script,
                             const TokenPosition& token_pos);
  bool LibraryMatchesFilters(const Library& lib);

  void PrintCallSitesData(JSONObject* jsobj,
                          const Function& func,
                          const Code& code);
  void PrintCoverageData(JSONObject* jsobj,
                         const Function& func,
                         const Code& code,
                         bool report_branch_coverage);
  void PrintPossibleBreakpointsData(JSONObject* jsobj,
                                    const Function& func,
                                    const Code& code);
  void PrintProfileData(JSONObject* jsobj, ProfileFunction* profile_function);
#if defined(DEBUG)
  void VerifyScriptTable();
#endif
  void PrintScriptTable(JSONArray* jsarr);

  void VisitFunction(JSONArray* jsarr, const Function& func);
  void VisitField(JSONArray* jsarr, const Field& field);
  void VisitLibrary(JSONArray* jsarr, const Library& lib);
  void VisitClosures(JSONArray* jsarr);
  // An entry in the script table.
  struct ScriptTableEntry {
    ScriptTableEntry() : key(NULL), index(-1), script(NULL) {}

    const String* key;
    intptr_t index;
    const Script* script;
  };

  // Needed for DirectChainedHashMap.
  struct ScriptTableTrait {
    typedef ScriptTableEntry* Value;
    typedef const ScriptTableEntry* Key;
    typedef ScriptTableEntry* Pair;

    static Key KeyOf(Pair kv) { return kv; }

    static Value ValueOf(Pair kv) { return kv; }

    static inline uword Hash(Key key) { return key->key->Hash(); }

    static inline bool IsKeyEqual(Pair kv, Key key) {
      return kv->script->ptr() == key->script->ptr();
    }
  };

  void CollectAllScripts(
      DirectChainedHashMap<ScriptTableTrait>* local_script_table,
      GrowableArray<ScriptTableEntry*>* local_script_table_entries);

  void CleanupCollectedScripts(
      DirectChainedHashMap<ScriptTableTrait>* local_script_table,
      GrowableArray<ScriptTableEntry*>* local_script_table_entries);

  void CollectConstConstructorCoverageFromScripts(
      GrowableArray<ScriptTableEntry*>* local_script_table_entries,
      JSONArray* ranges);

  intptr_t report_set_;
  CompileMode compile_mode_;
  bool report_lines_;
  const GrowableObjectArray& library_filters_;
  Thread* thread_;
  const Script* script_;
  TokenPosition start_pos_;
  TokenPosition end_pos_;
  Profile profile_;
  GrowableArray<ScriptTableEntry*> script_table_entries_;
  DirectChainedHashMap<ScriptTableTrait> script_table_;
  intptr_t next_script_index_;
  intptr_t late_error_class_id_ = ClassId::kIllegalCid;
};

}  // namespace dart

#endif  // !defined(PRODUCT) && !defined(DART_PRECOMPILED_RUNTIME)
#endif  // RUNTIME_VM_SOURCE_REPORT_H_
