// Copyright 2013 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef V8_COMPILER_GRAPH_VISUALIZER_H_
#define V8_COMPILER_GRAPH_VISUALIZER_H_

#include <stdio.h>
#include <fstream>  // NOLINT(readability/streams)
#include <iosfwd>
#include <memory>

#include "src/common/globals.h"
#include "src/handles/handles.h"

// Currently disabled due to no-usage and API leaks.
#if !defined(DISABLE_GRAPHS_STARBOARD)

namespace v8 {
namespace internal {

class OptimizedCompilationInfo;
class SharedFunctionInfo;
class SourcePosition;
namespace compiler {

class Graph;
class LiveRange;
class TopLevelLiveRange;
class Instruction;
class InstructionBlock;
class InstructionOperand;
class InstructionSequence;
class NodeOrigin;
class NodeOriginTable;
class RegisterAllocationData;
class Schedule;
class SourcePositionTable;

struct TurboJsonFile : public std::ofstream {
  TurboJsonFile(OptimizedCompilationInfo* info, std::ios_base::openmode mode);
  ~TurboJsonFile() override;
};

struct TurboCfgFile : public std::ofstream {
  explicit TurboCfgFile(Isolate* isolate = nullptr);
  ~TurboCfgFile() override;
};

struct SourcePositionAsJSON {
  explicit SourcePositionAsJSON(const SourcePosition& sp) : sp(sp) {}
  const SourcePosition& sp;
};

V8_INLINE V8_EXPORT_PRIVATE SourcePositionAsJSON
AsJSON(const SourcePosition& sp) {
  return SourcePositionAsJSON(sp);
}

struct NodeOriginAsJSON {
  explicit NodeOriginAsJSON(const NodeOrigin& no) : no(no) {}
  const NodeOrigin& no;
};

V8_INLINE V8_EXPORT_PRIVATE NodeOriginAsJSON AsJSON(const NodeOrigin& no) {
  return NodeOriginAsJSON(no);
}

std::ostream& operator<<(std::ostream& out, const SourcePositionAsJSON& pos);

// Small helper that deduplicates SharedFunctionInfos.
class V8_EXPORT_PRIVATE SourceIdAssigner {
 public:
  explicit SourceIdAssigner(size_t size) {
    printed_.reserve(size);
    source_ids_.reserve(size);
  }
  int GetIdFor(Handle<SharedFunctionInfo> shared);
  int GetIdAt(size_t pos) const { return source_ids_[pos]; }

 private:
  std::vector<Handle<SharedFunctionInfo>> printed_;
  std::vector<int> source_ids_;
};

void JsonPrintAllSourceWithPositions(std::ostream& os,
                                     OptimizedCompilationInfo* info,
                                     Isolate* isolate);

void JsonPrintFunctionSource(std::ostream& os, int source_id,
                             std::unique_ptr<char[]> function_name,
                             Handle<Script> script, Isolate* isolate,
                             Handle<SharedFunctionInfo> shared,
                             bool with_key = false);
std::unique_ptr<char[]> GetVisualizerLogFileName(OptimizedCompilationInfo* info,
                                                 const char* optional_base_dir,
                                                 const char* phase,
                                                 const char* suffix);

struct GraphAsJSON {
  GraphAsJSON(const Graph& g, SourcePositionTable* p, NodeOriginTable* o)
      : graph(g), positions(p), origins(o) {}
  const Graph& graph;
  const SourcePositionTable* positions;
  const NodeOriginTable* origins;
};

V8_INLINE V8_EXPORT_PRIVATE GraphAsJSON AsJSON(const Graph& g,
                                               SourcePositionTable* p,
                                               NodeOriginTable* o) {
  return GraphAsJSON(g, p, o);
}

V8_EXPORT_PRIVATE std::ostream& operator<<(std::ostream& os,
                                           const GraphAsJSON& ad);

struct AsRPO {
  explicit AsRPO(const Graph& g) : graph(g) {}
  const Graph& graph;
};

V8_EXPORT_PRIVATE std::ostream& operator<<(std::ostream& os, const AsRPO& ad);

struct AsC1VCompilation {
  explicit AsC1VCompilation(const OptimizedCompilationInfo* info)
      : info_(info) {}
  const OptimizedCompilationInfo* info_;
};

struct AsScheduledGraph {
  explicit AsScheduledGraph(const Schedule* schedule) : schedule(schedule) {}
  const Schedule* schedule;
};

std::ostream& operator<<(std::ostream& os, const AsScheduledGraph& scheduled);
struct AsC1V {
  AsC1V(const char* phase, const Schedule* schedule,
        const SourcePositionTable* positions = nullptr,
        const InstructionSequence* instructions = nullptr)
      : schedule_(schedule),
        instructions_(instructions),
        positions_(positions),
        phase_(phase) {}
  const Schedule* schedule_;
  const InstructionSequence* instructions_;
  const SourcePositionTable* positions_;
  const char* phase_;
};

struct AsC1VRegisterAllocationData {
  explicit AsC1VRegisterAllocationData(
      const char* phase, const RegisterAllocationData* data = nullptr)
      : phase_(phase), data_(data) {}
  const char* phase_;
  const RegisterAllocationData* data_;
};

std::ostream& operator<<(std::ostream& os, const AsC1VCompilation& ac);
std::ostream& operator<<(std::ostream& os, const AsC1V& ac);
std::ostream& operator<<(std::ostream& os,
                         const AsC1VRegisterAllocationData& ac);

struct LiveRangeAsJSON {
  const LiveRange& range_;
  const InstructionSequence& code_;
};

std::ostream& operator<<(std::ostream& os,
                         const LiveRangeAsJSON& live_range_json);

struct TopLevelLiveRangeAsJSON {
  const TopLevelLiveRange& range_;
  const InstructionSequence& code_;
};

std::ostream& operator<<(
    std::ostream& os, const TopLevelLiveRangeAsJSON& top_level_live_range_json);

struct RegisterAllocationDataAsJSON {
  const RegisterAllocationData& data_;
  const InstructionSequence& code_;
};

std::ostream& operator<<(std::ostream& os,
                         const RegisterAllocationDataAsJSON& ac);

struct InstructionOperandAsJSON {
  const InstructionOperand* op_;
  const InstructionSequence* code_;
};

std::ostream& operator<<(std::ostream& os, const InstructionOperandAsJSON& o);

struct InstructionAsJSON {
  int index_;
  const Instruction* instr_;
  const InstructionSequence* code_;
};
std::ostream& operator<<(std::ostream& os, const InstructionAsJSON& i);

struct InstructionBlockAsJSON {
  const InstructionBlock* block_;
  const InstructionSequence* code_;
};

std::ostream& operator<<(std::ostream& os, const InstructionBlockAsJSON& b);

struct InstructionSequenceAsJSON {
  const InstructionSequence* sequence_;
};
std::ostream& operator<<(std::ostream& os, const InstructionSequenceAsJSON& s);

}  // namespace compiler
}  // namespace internal
}  // namespace v8

#endif  // DISABLE_GRAPHS_STARBOARD

#endif  // V8_COMPILER_GRAPH_VISUALIZER_H_
