/*
 * 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/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 "utils/arena_allocator.h"

#include "gtest/gtest.h"

namespace art {

static void TestCode(const uint16_t* data, const char* expected) {
  ArenaPool pool;
  ArenaAllocator allocator(&pool);
  HGraphBuilder builder(&allocator);
  const DexFile::CodeItem* item = reinterpret_cast<const DexFile::CodeItem*>(data);
  HGraph* graph = builder.BuildGraph(*item);
  ASSERT_NE(graph, nullptr);
  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"
    "  5: SuspendCheck\n"
    "  6: 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: SuspendCheck\n"
    "  3: Goto 2\n"
    "BasicBlock 4, pred: 2\n"
    "  4: 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"
    "  4: SuspendCheck\n"
    "  5: Goto 1\n"
    "BasicBlock 1, pred: 0, 2, succ: 3\n"
    "  0: ReturnVoid\n"
    "BasicBlock 2, succ: 1\n"
    "  1: SuspendCheck\n"
    "  2: Goto 1\n"
    "BasicBlock 3, pred: 1\n"
    "  3: 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
