/*
 * 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.
 */

#include "base/arena_allocator.h"
#include "base/stringprintf.h"
#include "builder.h"
#include "dex_file.h"
#include "dex_instruction.h"
#include "nodes.h"
#include "optimizing_unit_test.h"
#include "pretty_printer.h"

#include "gtest/gtest.h"

namespace art {

static void TestCode(const uint16_t* data, const char* expected) {
  ArenaPool pool;
  ArenaAllocator allocator(&pool);
  HGraph* graph = CreateGraph(&allocator);
  HGraphBuilder builder(graph);
  const DexFile::CodeItem* item = reinterpret_cast<const DexFile::CodeItem*>(data);
  bool graph_built = builder.BuildGraph(*item);
  ASSERT_TRUE(graph_built);
  StringPrettyPrinter printer(graph);
  printer.VisitInsertionOrder();
  ASSERT_STREQ(expected, printer.str().c_str());
}

TEST(PrettyPrinterTest, ReturnVoid) {
  const uint16_t data[] = ZERO_REGISTER_CODE_ITEM(
      Instruction::RETURN_VOID);

  const char* expected =
      "BasicBlock 0, succ: 1\n"
      "  2: SuspendCheck\n"
      "  3: Goto 1\n"
      "BasicBlock 1, pred: 0, succ: 2\n"
      "  0: ReturnVoid\n"
      "BasicBlock 2, pred: 1\n"
      "  1: Exit\n";

  TestCode(data, expected);
}

TEST(PrettyPrinterTest, CFG1) {
  const char* expected =
    "BasicBlock 0, succ: 1\n"
    "  3: SuspendCheck\n"
    "  4: Goto 1\n"
    "BasicBlock 1, pred: 0, succ: 2\n"
    "  0: Goto 2\n"
    "BasicBlock 2, pred: 1, succ: 3\n"
    "  1: ReturnVoid\n"
    "BasicBlock 3, pred: 2\n"
    "  2: Exit\n";

  const uint16_t data[] =
    ZERO_REGISTER_CODE_ITEM(
      Instruction::GOTO | 0x100,
      Instruction::RETURN_VOID);

  TestCode(data, expected);
}

TEST(PrettyPrinterTest, CFG2) {
  const char* expected =
    "BasicBlock 0, succ: 1\n"
    "  4: SuspendCheck\n"
    "  5: Goto 1\n"
    "BasicBlock 1, pred: 0, succ: 2\n"
    "  0: Goto 2\n"
    "BasicBlock 2, pred: 1, succ: 3\n"
    "  1: Goto 3\n"
    "BasicBlock 3, pred: 2, succ: 4\n"
    "  2: ReturnVoid\n"
    "BasicBlock 4, pred: 3\n"
    "  3: Exit\n";

  const uint16_t data[] = ZERO_REGISTER_CODE_ITEM(
    Instruction::GOTO | 0x100,
    Instruction::GOTO | 0x100,
    Instruction::RETURN_VOID);

  TestCode(data, expected);
}

TEST(PrettyPrinterTest, CFG3) {
  const char* expected =
    "BasicBlock 0, succ: 1\n"
    "  4: SuspendCheck\n"
    "  5: Goto 1\n"
    "BasicBlock 1, pred: 0, succ: 3\n"
    "  0: Goto 3\n"
    "BasicBlock 2, pred: 3, succ: 4\n"
    "  1: ReturnVoid\n"
    "BasicBlock 3, pred: 1, succ: 2\n"
    "  2: Goto 2\n"
    "BasicBlock 4, pred: 2\n"
    "  3: Exit\n";

  const uint16_t data1[] = ZERO_REGISTER_CODE_ITEM(
    Instruction::GOTO | 0x200,
    Instruction::RETURN_VOID,
    Instruction::GOTO | 0xFF00);

  TestCode(data1, expected);

  const uint16_t data2[] = ZERO_REGISTER_CODE_ITEM(
    Instruction::GOTO_16, 3,
    Instruction::RETURN_VOID,
    Instruction::GOTO_16, 0xFFFF);

  TestCode(data2, expected);

  const uint16_t data3[] = ZERO_REGISTER_CODE_ITEM(
    Instruction::GOTO_32, 4, 0,
    Instruction::RETURN_VOID,
    Instruction::GOTO_32, 0xFFFF, 0xFFFF);

  TestCode(data3, expected);
}

TEST(PrettyPrinterTest, CFG4) {
  const char* expected =
    "BasicBlock 0, succ: 1\n"
    "  3: SuspendCheck\n"
    "  4: Goto 1\n"
    "BasicBlock 1, pred: 0, 1, succ: 1\n"
    "  0: SuspendCheck\n"
    "  1: Goto 1\n"
    "BasicBlock 2\n"
    "  2: Exit\n";

  const uint16_t data1[] = ZERO_REGISTER_CODE_ITEM(
    Instruction::NOP,
    Instruction::GOTO | 0xFF00);

  TestCode(data1, expected);

  const uint16_t data2[] = ZERO_REGISTER_CODE_ITEM(
    Instruction::GOTO_32, 0, 0);

  TestCode(data2, expected);
}

TEST(PrettyPrinterTest, CFG5) {
  const char* expected =
    "BasicBlock 0, succ: 1\n"
    "  3: SuspendCheck\n"
    "  4: Goto 1\n"
    "BasicBlock 1, pred: 0, 2, succ: 3\n"
    "  0: ReturnVoid\n"
    "BasicBlock 2, succ: 1\n"
    "  1: Goto 1\n"
    "BasicBlock 3, pred: 1\n"
    "  2: Exit\n";

  const uint16_t data[] = ZERO_REGISTER_CODE_ITEM(
    Instruction::RETURN_VOID,
    Instruction::GOTO | 0x100,
    Instruction::GOTO | 0xFE00);

  TestCode(data, expected);
}

TEST(PrettyPrinterTest, CFG6) {
  const char* expected =
    "BasicBlock 0, succ: 1\n"
    "  0: Local [4, 3, 2]\n"
    "  1: IntConstant [2]\n"
    "  10: SuspendCheck\n"
    "  11: Goto 1\n"
    "BasicBlock 1, pred: 0, succ: 3, 2\n"
    "  2: StoreLocal(0, 1)\n"
    "  3: LoadLocal(0) [5]\n"
    "  4: LoadLocal(0) [5]\n"
    "  5: Equal(3, 4) [6]\n"
    "  6: If(5)\n"
    "BasicBlock 2, pred: 1, succ: 3\n"
    "  7: Goto 3\n"
    "BasicBlock 3, pred: 1, 2, succ: 4\n"
    "  8: ReturnVoid\n"
    "BasicBlock 4, pred: 3\n"
    "  9: Exit\n";

  const uint16_t data[] = ONE_REGISTER_CODE_ITEM(
    Instruction::CONST_4 | 0 | 0,
    Instruction::IF_EQ, 3,
    Instruction::GOTO | 0x100,
    Instruction::RETURN_VOID);

  TestCode(data, expected);
}

TEST(PrettyPrinterTest, CFG7) {
  const char* expected =
    "BasicBlock 0, succ: 1\n"
    "  0: Local [4, 3, 2]\n"
    "  1: IntConstant [2]\n"
    "  11: SuspendCheck\n"
    "  12: Goto 1\n"
    "BasicBlock 1, pred: 0, succ: 3, 2\n"
    "  2: StoreLocal(0, 1)\n"
    "  3: LoadLocal(0) [5]\n"
    "  4: LoadLocal(0) [5]\n"
    "  5: Equal(3, 4) [6]\n"
    "  6: If(5)\n"
    "BasicBlock 2, pred: 1, 3, succ: 3\n"
    "  7: Goto 3\n"
    "BasicBlock 3, pred: 1, 2, succ: 2\n"
    "  8: SuspendCheck\n"
    "  9: Goto 2\n"
    "BasicBlock 4\n"
    "  10: Exit\n";

  const uint16_t data[] = ONE_REGISTER_CODE_ITEM(
    Instruction::CONST_4 | 0 | 0,
    Instruction::IF_EQ, 3,
    Instruction::GOTO | 0x100,
    Instruction::GOTO | 0xFF00);

  TestCode(data, expected);
}

TEST(PrettyPrinterTest, IntConstant) {
  const char* expected =
    "BasicBlock 0, succ: 1\n"
    "  0: Local [2]\n"
    "  1: IntConstant [2]\n"
    "  5: SuspendCheck\n"
    "  6: Goto 1\n"
    "BasicBlock 1, pred: 0, succ: 2\n"
    "  2: StoreLocal(0, 1)\n"
    "  3: ReturnVoid\n"
    "BasicBlock 2, pred: 1\n"
    "  4: Exit\n";

  const uint16_t data[] = ONE_REGISTER_CODE_ITEM(
    Instruction::CONST_4 | 0 | 0,
    Instruction::RETURN_VOID);

  TestCode(data, expected);
}
}  // namespace art
