/*
 * Copyright (C) 2014 The Android Open Source Project
 *
 * 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.
 */

#ifndef ART_COMPILER_OPTIMIZING_PRETTY_PRINTER_H_
#define ART_COMPILER_OPTIMIZING_PRETTY_PRINTER_H_

#include "android-base/stringprintf.h"

#include "base/macros.h"
#include "nodes.h"

namespace art HIDDEN {

class HPrettyPrinter : public HGraphVisitor {
 public:
  explicit HPrettyPrinter(HGraph* graph) : HGraphVisitor(graph) { }

  void PrintPreInstruction(HInstruction* instruction) {
    PrintString("  ");
    PrintInt(instruction->GetId());
    PrintString(": ");
  }

  void VisitInstruction(HInstruction* instruction) override {
    PrintPreInstruction(instruction);
    PrintString(instruction->DebugName());
    PrintPostInstruction(instruction);
  }

  void PrintPostInstruction(HInstruction* instruction) {
    HConstInputsRef inputs = instruction->GetInputs();
    if (!inputs.empty()) {
      PrintString("(");
      bool first = true;
      for (const HInstruction* input : inputs) {
        if (first) {
          first = false;
        } else {
          PrintString(", ");
        }
        PrintInt(input->GetId());
      }
      PrintString(")");
    }
    if (instruction->HasUses()) {
      PrintString(" [");
      bool first = true;
      for (const HUseListNode<HInstruction*>& use : instruction->GetUses()) {
        if (first) {
          first = false;
        } else {
          PrintString(", ");
        }
        PrintInt(use.GetUser()->GetId());
      }
      PrintString("]");
    }
    PrintNewLine();
  }

  void VisitBasicBlock(HBasicBlock* block) override {
    PrintString("BasicBlock ");
    PrintInt(block->GetBlockId());
    const ArenaVector<HBasicBlock*>& predecessors = block->GetPredecessors();
    if (!predecessors.empty()) {
      PrintString(", pred: ");
      for (size_t i = 0; i < predecessors.size() -1; i++) {
        PrintInt(predecessors[i]->GetBlockId());
        PrintString(", ");
      }
      PrintInt(predecessors.back()->GetBlockId());
    }
    const ArenaVector<HBasicBlock*>& successors = block->GetSuccessors();
    if (!successors.empty()) {
      PrintString(", succ: ");
      for (size_t i = 0; i < successors.size() - 1; i++) {
        PrintInt(successors[i]->GetBlockId());
        PrintString(", ");
      }
      PrintInt(successors.back()->GetBlockId());
    }
    PrintNewLine();
    HGraphVisitor::VisitBasicBlock(block);
  }

  virtual void PrintNewLine() = 0;
  virtual void PrintInt(int value) = 0;
  virtual void PrintString(const char* value) = 0;

 private:
  DISALLOW_COPY_AND_ASSIGN(HPrettyPrinter);
};

class StringPrettyPrinter : public HPrettyPrinter {
 public:
  explicit StringPrettyPrinter(HGraph* graph)
      : HPrettyPrinter(graph), str_(""), current_block_(nullptr) { }

  void PrintInt(int value) override {
    str_ += android::base::StringPrintf("%d", value);
  }

  void PrintString(const char* value) override {
    str_ += value;
  }

  void PrintNewLine() override {
    str_ += '\n';
  }

  void Clear() { str_.clear(); }

  std::string str() const { return str_; }

  void VisitBasicBlock(HBasicBlock* block) override {
    current_block_ = block;
    HPrettyPrinter::VisitBasicBlock(block);
  }

  void VisitGoto(HGoto* gota) override {
    PrintString("  ");
    PrintInt(gota->GetId());
    PrintString(": Goto ");
    PrintInt(current_block_->GetSuccessors()[0]->GetBlockId());
    PrintNewLine();
  }

 private:
  std::string str_;
  HBasicBlock* current_block_;

  DISALLOW_COPY_AND_ASSIGN(StringPrettyPrinter);
};

}  // namespace art

#endif  // ART_COMPILER_OPTIMIZING_PRETTY_PRINTER_H_
