/*
 * Copyright (C) 2019 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 "common/debug.h"
#include "compiler/compiler.h"
#include "inode2filename/inode_resolver.h"

#include <cstdio>
#include <fstream>
#include <string>
#include <vector>

#include <android-base/file.h>
#include <gtest/gtest.h>

namespace iorap::compiler {

static std::string GetTestDataPath(const std::string& fn) {
  static std::string exec_dir = android::base::GetExecutableDirectory();
  return exec_dir + "/tests/src/compiler/testdata/" + fn;
}

class CompilerTest: public ::testing::Test{
 protected:
  void SetUp() override {
    ir_dependencies.data_source = inode2filename::DataSourceKind::kTextCache;
    ir_dependencies.text_cache_filename = GetTestDataPath("common_textcache");
    ir_dependencies.verify = inode2filename::VerifyKind::kNone;  // required for determinism.
    ir_dependencies.root_directories.push_back("/system");
    ir_dependencies.root_directories.push_back("/apex");
    ir_dependencies.root_directories.push_back("/data");
    ir_dependencies.root_directories.push_back("/vendor");
    ir_dependencies.root_directories.push_back("/product");
    ir_dependencies.root_directories.push_back("/metadata");
  }

  inode2filename::InodeResolverDependencies ir_dependencies;
};

TEST_F(CompilerTest, SingleTraceDuration) {
  std::vector<std::string> input_file_names{GetTestDataPath("common_perfetto_trace.pb")};
  std::vector<uint64_t> timestamp_limit_ns{260390390018596UL};
  TemporaryFile tmp_file;
  char* output_file_name = tmp_file.path;
  bool output_proto = false;


  std::vector<CompilationInput> perfetto_traces =
      MakeCompilationInputs(input_file_names, timestamp_limit_ns, /*pids=*/{});
  bool result = PerformCompilation(perfetto_traces,
                                   output_file_name,
                                   output_proto,
                                   /*blacklist_filter*/std::nullopt,
                                   ir_dependencies);
  std::ifstream ifs(output_file_name);

  // The extra paren is needed to avoid compilation error:
  // "parentheses were disambiguated as a function declaration".
  std::string content{std::istreambuf_iterator<char>(ifs),
    std::istreambuf_iterator<char>()};

  EXPECT_EQ(result, true);
  EXPECT_EQ(content, "{filename:\"/product/app/CalculatorGooglePrebuilt/"
            "CalculatorGooglePrebuilt.apk\","
            "timestamp:7641303,"
            "add_to_page_cache:1,"
            "index:540}\n");
}

TEST_F(CompilerTest, MultiTraceDuration) {
  std::vector<std::string> input_file_names{GetTestDataPath("common_perfetto_trace.pb"),
    GetTestDataPath("common_perfetto_trace2.pb")};
  std::vector<uint64_t> timestamp_limit_ns{260390390018596UL, 333215840452006UL};
  TemporaryFile tmp_file;
  char* output_file_name = tmp_file.path;
  bool output_proto = false;

  std::vector<CompilationInput> perfetto_traces =
      MakeCompilationInputs(input_file_names, timestamp_limit_ns, /*pids=*/{});
  bool result = PerformCompilation(perfetto_traces,
                                   output_file_name,
                                   output_proto,
                                   /*blacklist_filter*/std::nullopt,
                                   ir_dependencies);
  std::ifstream ifs(output_file_name);
  std::string content{std::istreambuf_iterator<char>(ifs),
    std::istreambuf_iterator<char>()};

  EXPECT_EQ(result, true);
  EXPECT_EQ(content, "{filename:\"/apex/com.android.art/lib64/libperfetto_hprof.so\","
            "timestamp:4388958,"
            "add_to_page_cache:1,"
            "index:227}\n"
            "{filename:\"/product/app/CalculatorGooglePrebuilt/"
            "CalculatorGooglePrebuilt.apk\","
            "timestamp:7641303,"
            "add_to_page_cache:1,"
            "index:540}\n");
}

TEST_F(CompilerTest, NoTraceDuration) {
  std::vector<std::string> input_file_names{GetTestDataPath("common_perfetto_trace.pb")};
  TemporaryFile tmp_file;
  char* output_file_name = tmp_file.path;
  bool output_proto = false;

  std::vector<CompilationInput> perfetto_traces =
      MakeCompilationInputs(input_file_names, /* timestamp_limit_ns= */{}, /*pids=*/{});
  bool result = PerformCompilation(perfetto_traces,
                                   output_file_name,
                                   output_proto,
                                   /*blacklist_filter*/std::nullopt,
                                   ir_dependencies);
  std::ifstream ifs(output_file_name);
  size_t line_num = std::count((std::istreambuf_iterator<char>(ifs)),
                               (std::istreambuf_iterator<char>()),
                               '\n');

  EXPECT_EQ(result, true);
  EXPECT_EQ(line_num, 1675UL);
}

TEST_F(CompilerTest, BlacklistFilterArtFiles) {
  std::vector<std::string> input_file_names{GetTestDataPath("common_perfetto_trace.pb")};
  TemporaryFile tmp_file;
  char* output_file_name = tmp_file.path;
  bool output_proto = false;

  std::string blacklist_filter = "[.](art|oat|odex|vdex|dex)$";

  // iorap.cmd.compiler -op output.pb -it common_textcache -ot
  //                    --denylist-filter "[.](art|oat|odex|vdex|dex)$" common_perfetto_trace.pb

  std::vector<CompilationInput> perfetto_traces =
      MakeCompilationInputs(input_file_names, /* timestamp_limit_ns= */{}, /*pids=*/{});
  bool result = PerformCompilation(perfetto_traces,
                                   output_file_name,
                                   output_proto,
                                     blacklist_filter,
                                   ir_dependencies);
  std::ifstream ifs(output_file_name);
  size_t line_num = std::count((std::istreambuf_iterator<char>(ifs)),
                               (std::istreambuf_iterator<char>()),
                               '\n');

  EXPECT_EQ(result, true);
  EXPECT_EQ(line_num, 1617UL);
}

TEST_F(CompilerTest, PidFilter) {
  std::vector<std::string> input_file_names{GetTestDataPath("common_perfetto_trace.pb")};
  TemporaryFile tmp_file;
  char* output_file_name = tmp_file.path;
  bool output_proto = false;

  std::vector<CompilationInput> perfetto_traces =
      MakeCompilationInputs(input_file_names, /*timestamp_limit_ns=*/{}, /*pids=*/{30716});
  bool result = PerformCompilation(perfetto_traces,
                                   output_file_name,
                                   output_proto,
                                   /*deny_filter*/std::nullopt,
                                   ir_dependencies);
  std::ifstream ifs(output_file_name);
  size_t line_num = std::count((std::istreambuf_iterator<char>(ifs)),
                               (std::istreambuf_iterator<char>()),
                               '\n');

  EXPECT_EQ(result, true);
  EXPECT_EQ(line_num, 13UL);
}
}  // namespace iorap::compiler
