/*
 * Copyright (C) 2021 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 "app_info.h"

#include <vector>

#include "gtest/gtest.h"

namespace art HIDDEN {

TEST(AppInfoTest, RegisterAppInfo) {
  AppInfo app_info;
  EXPECT_FALSE(app_info.HasRegisteredAppInfo());
  EXPECT_EQ(app_info.GetRegisteredCodeType("code_location"), AppInfo::CodeType::kUnknown);

  app_info.RegisterAppInfo(
      "package_name",
      std::vector<std::string>({"code_location"}),
      "",
      "",
      AppInfo::CodeType::kPrimaryApk);
  EXPECT_TRUE(app_info.HasRegisteredAppInfo());
  EXPECT_EQ(app_info.GetRegisteredCodeType("code_location"), AppInfo::CodeType::kPrimaryApk);

  std::string filter;
  std::string reason;
  app_info.GetPrimaryApkOptimizationStatus(&filter, &reason);

  // Odex status was not registered.
  ASSERT_EQ(filter, "unknown");
  ASSERT_EQ(reason, "unknown");
}

TEST(AppInfoTest, RegisterAppInfoWithOdexStatus) {
  AppInfo app_info;
  app_info.RegisterAppInfo(
      "package_name",
      std::vector<std::string>({"code_location"}),
      "",
      "",
      AppInfo::CodeType::kPrimaryApk);
  EXPECT_EQ(app_info.GetRegisteredCodeType("code_location"), AppInfo::CodeType::kPrimaryApk);
  app_info.RegisterOdexStatus(
      "code_location",
      "filter",
      "reason",
      "odex_status");
  EXPECT_EQ(app_info.GetRegisteredCodeType("code_location"), AppInfo::CodeType::kPrimaryApk);

  std::string filter;
  std::string reason;
  app_info.GetPrimaryApkOptimizationStatus(&filter, &reason);

  ASSERT_EQ(filter, "filter");
  ASSERT_EQ(reason, "reason");
}

TEST(AppInfoTest, RegisterAppInfoWithOdexStatusMultiplePrimary) {
  AppInfo app_info;
  app_info.RegisterOdexStatus(
      "code_location",
      "filter",
      "reason",
      "odex_status");
  EXPECT_FALSE(app_info.HasRegisteredAppInfo());
  app_info.RegisterOdexStatus(
      "code_location2",
      "filter2",
      "reason2",
      "odex_status");
  EXPECT_FALSE(app_info.HasRegisteredAppInfo());
  app_info.RegisterAppInfo(
      "package_name",
      std::vector<std::string>({"code_location"}),
      "",
      "",
      AppInfo::CodeType::kPrimaryApk);
  EXPECT_TRUE(app_info.HasRegisteredAppInfo());
  EXPECT_EQ(app_info.GetRegisteredCodeType("code_location"), AppInfo::CodeType::kPrimaryApk);
  EXPECT_EQ(app_info.GetRegisteredCodeType("code_location2"), AppInfo::CodeType::kUnknown);

  std::string filter;
  std::string reason;
  app_info.GetPrimaryApkOptimizationStatus(&filter, &reason);

  // The optimization status should be the one of the first apk.
  ASSERT_EQ(filter, "filter");
  ASSERT_EQ(reason, "reason");
}

TEST(AppInfoTest, RegisterAppInfoWithOdexStatusNoPrimary) {
  AppInfo app_info;

  // Check that the status is not known in an empty app_info.
  std::string filter;
  std::string reason;
  app_info.GetPrimaryApkOptimizationStatus(&filter, &reason);

  // Register a split.s
  app_info.RegisterAppInfo(
      "package_name",
      std::vector<std::string>({"code_location"}),
      "",
      "",
      AppInfo::CodeType::kSplitApk);
  app_info.RegisterOdexStatus(
      "code_location",
      "filter",
      "reason",
      "odex_status");
  EXPECT_EQ(app_info.GetRegisteredCodeType("code_location"), AppInfo::CodeType::kSplitApk);

  // The optimization status is unknown since we don't have primary apks.
  app_info.GetPrimaryApkOptimizationStatus(&filter, &reason);
  ASSERT_EQ(filter, "unknown");
  ASSERT_EQ(reason, "unknown");
}

}  // namespace art
