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

#include "common_runtime_test.h"
#include "instruction_set_features.h"

#include <gtest/gtest.h>

#ifdef ART_TARGET_ANDROID
#include <android-base/properties.h>
#endif

#include <android-base/logging.h>
#include <android-base/stringprintf.h>

namespace art {

#ifdef ART_TARGET_ANDROID

using android::base::StringPrintf;

#if defined(__aarch64__)
TEST(InstructionSetFeaturesTest, DISABLED_FeaturesFromSystemPropertyVariant) {
  LOG(WARNING) << "Test disabled due to no CPP define for A53 erratum 835769";
#else
TEST(InstructionSetFeaturesTest, FeaturesFromSystemPropertyVariant) {
#endif
  if (kIsTargetBuild) {
    // atest differs in build-time and run-time features.
    TEST_DISABLED_FOR_X86();
    TEST_DISABLED_FOR_X86_64();
  }

  // Take the default set of instruction features from the build.
  std::unique_ptr<const InstructionSetFeatures> instruction_set_features(
      InstructionSetFeatures::FromCppDefines());

  // Read the variant property.
  std::string key = StringPrintf("dalvik.vm.isa.%s.variant", GetInstructionSetString(kRuntimeISA));
  std::string dex2oat_isa_variant = android::base::GetProperty(key, "");
  if (!dex2oat_isa_variant.empty()) {
    // Use features from property to build InstructionSetFeatures and check against build's
    // features.
    std::string error_msg;
    std::unique_ptr<const InstructionSetFeatures> property_features(
        InstructionSetFeatures::FromVariant(kRuntimeISA, dex2oat_isa_variant, &error_msg));
    ASSERT_TRUE(property_features.get() != nullptr) << error_msg;

    EXPECT_TRUE(property_features->HasAtLeast(instruction_set_features.get()))
      << "System property features: " << *property_features.get()
      << "\nFeatures from build: " << *instruction_set_features.get();
  }
}

#if defined(__aarch64__)
TEST(InstructionSetFeaturesTest, DISABLED_FeaturesFromSystemPropertyString) {
  LOG(WARNING) << "Test disabled due to no CPP define for A53 erratum 835769";
#else
TEST(InstructionSetFeaturesTest, FeaturesFromSystemPropertyString) {
#endif
  if (kIsTargetBuild) {
    // atest differs in build-time and run-time features.
    TEST_DISABLED_FOR_X86();
    TEST_DISABLED_FOR_X86_64();
  }

  // Take the default set of instruction features from the build.
  std::unique_ptr<const InstructionSetFeatures> instruction_set_features(
      InstructionSetFeatures::FromCppDefines());

  // Read the variant property.
  std::string variant_key = StringPrintf("dalvik.vm.isa.%s.variant",
                                         GetInstructionSetString(kRuntimeISA));
  std::string dex2oat_isa_variant = android::base::GetProperty(variant_key, "");
  if (!dex2oat_isa_variant.empty()) {
    // Read the features property.
    std::string features_key = StringPrintf("dalvik.vm.isa.%s.features",
                                            GetInstructionSetString(kRuntimeISA));
    std::string dex2oat_isa_features = android::base::GetProperty(features_key, "");
    if (!dex2oat_isa_features.empty()) {
      // Use features from property to build InstructionSetFeatures and check against build's
      // features.
      std::string error_msg;
      std::unique_ptr<const InstructionSetFeatures> base_features(
          InstructionSetFeatures::FromVariant(kRuntimeISA, dex2oat_isa_variant, &error_msg));
      ASSERT_TRUE(base_features.get() != nullptr) << error_msg;

      std::unique_ptr<const InstructionSetFeatures> property_features(
          base_features->AddFeaturesFromString(dex2oat_isa_features, &error_msg));
      ASSERT_TRUE(property_features.get() != nullptr) << error_msg;

      EXPECT_TRUE(property_features->HasAtLeast(instruction_set_features.get()))
      << "System property features: " << *property_features.get()
      << "\nFeatures from build: " << *instruction_set_features.get();
    }
  }
}

#if defined(__arm__)
TEST(InstructionSetFeaturesTest, DISABLED_FeaturesFromCpuInfo) {
  LOG(WARNING) << "Test disabled due to buggy ARM kernels";
#else
TEST(InstructionSetFeaturesTest, FeaturesFromCpuInfo) {
#endif
  // Take the default set of instruction features from the build.
  std::unique_ptr<const InstructionSetFeatures> instruction_set_features(
      InstructionSetFeatures::FromCppDefines());

  // Check we get the same instruction set features using /proc/cpuinfo.
  std::unique_ptr<const InstructionSetFeatures> cpuinfo_features(
      InstructionSetFeatures::FromCpuInfo());
  EXPECT_TRUE(cpuinfo_features->HasAtLeast(instruction_set_features.get()))
      << "CPU Info features: " << *cpuinfo_features.get()
      << "\nFeatures from build: " << *instruction_set_features.get();
}
#endif

#ifndef ART_TARGET_ANDROID
TEST(InstructionSetFeaturesTest, HostFeaturesFromCppDefines) {
  std::string error_msg;
  std::unique_ptr<const InstructionSetFeatures> default_features(
      InstructionSetFeatures::FromVariant(kRuntimeISA, "default", &error_msg));
  ASSERT_TRUE(error_msg.empty());

  std::unique_ptr<const InstructionSetFeatures> cpp_features(
      InstructionSetFeatures::FromCppDefines());
  EXPECT_TRUE(cpp_features->HasAtLeast(default_features.get()))
      << "Default variant features: " << *default_features.get()
      << "\nFeatures from build: " << *cpp_features.get();
}
#endif

#if defined(__arm__)
TEST(InstructionSetFeaturesTest, DISABLED_FeaturesFromHwcap) {
  LOG(WARNING) << "Test disabled due to buggy ARM kernels";
#else
TEST(InstructionSetFeaturesTest, FeaturesFromHwcap) {
#endif
  // Take the default set of instruction features from the build.
  std::unique_ptr<const InstructionSetFeatures> instruction_set_features(
      InstructionSetFeatures::FromCppDefines());

  // Check we get the same instruction set features using AT_HWCAP.
  std::unique_ptr<const InstructionSetFeatures> hwcap_features(
      InstructionSetFeatures::FromHwcap());
  EXPECT_TRUE(hwcap_features->HasAtLeast(instruction_set_features.get()))
      << "Hwcap features: " << *hwcap_features.get()
      << "\nFeatures from build: " << *instruction_set_features.get();
}

TEST(InstructionSetFeaturesTest, FeaturesFromAssembly) {
  // Take the default set of instruction features from the build.
  std::unique_ptr<const InstructionSetFeatures> instruction_set_features(
      InstructionSetFeatures::FromCppDefines());

  // Check we get the same instruction set features using assembly tests.
  std::unique_ptr<const InstructionSetFeatures> assembly_features(
      InstructionSetFeatures::FromAssembly());
  EXPECT_TRUE(assembly_features->HasAtLeast(instruction_set_features.get()))
      << "Assembly features: " << *assembly_features.get()
      << "\nFeatures from build: " << *instruction_set_features.get();
}

TEST(InstructionSetFeaturesTest, FeaturestFromCpuFeatures) {
  // Take the default set of instruction features from the build.
  std::unique_ptr<const InstructionSetFeatures> instruction_set_features(
      InstructionSetFeatures::FromCppDefines());

  // Check we get the same instruction set features using the cpu_features library
  std::unique_ptr<const InstructionSetFeatures> library_features(
      InstructionSetFeatures::FromCpuFeatures());

  EXPECT_TRUE(library_features->HasAtLeast(instruction_set_features.get()))
      << "Library features: " << *library_features.get()
      << "\nFeatures from build: " << *instruction_set_features.get();
}

TEST(InstructionSetFeaturesTest, FeaturesFromRuntimeDetection) {
  if (!InstructionSetFeatures::IsRuntimeDetectionSupported()) {
    EXPECT_EQ(InstructionSetFeatures::FromRuntimeDetection(), nullptr);
  }
}

// The instruction set feature string must not contain 'default' together with
// other feature names.
//
// Test that InstructionSetFeatures::AddFeaturesFromString returns nullptr and
// an error is reported when the value 'default' is specified together
// with other feature names in an instruction set feature string.
TEST(InstructionSetFeaturesTest, AddFeaturesFromStringWithDefaultAndOtherNames) {
  std::unique_ptr<const InstructionSetFeatures> cpp_defined_features(
      InstructionSetFeatures::FromCppDefines());
  std::vector<std::string> invalid_feature_strings = {
    "a,default",
    "default,a",
    "a,default,b",
    "a,b,default",
    "default,a,b,c",
    "a,b,default,c,d",
    "a, default ",
    " default , a",
    "a, default , b",
    "default,runtime"
  };

  for (const std::string& invalid_feature_string : invalid_feature_strings) {
    std::string error_msg;
    EXPECT_EQ(cpp_defined_features->AddFeaturesFromString(invalid_feature_string, &error_msg),
              nullptr) << " Invalid feature string: '" << invalid_feature_string << "'";
    EXPECT_EQ(error_msg,
              "Specific instruction set feature(s) cannot be used when 'default' is used.");
  }
}

// The instruction set feature string must not contain 'runtime' together with
// other feature names.
//
// Test that InstructionSetFeatures::AddFeaturesFromString returns nullptr and
// an error is reported when the value 'runtime' is specified together
// with other feature names in an instruction set feature string.
TEST(InstructionSetFeaturesTest, AddFeaturesFromStringWithRuntimeAndOtherNames) {
  std::unique_ptr<const InstructionSetFeatures> cpp_defined_features(
      InstructionSetFeatures::FromCppDefines());
  std::vector<std::string> invalid_feature_strings = {
    "a,runtime",
    "runtime,a",
    "a,runtime,b",
    "a,b,runtime",
    "runtime,a,b,c",
    "a,b,runtime,c,d",
    "a, runtime ",
    " runtime , a",
    "a, runtime , b",
    "runtime,default"
  };

  for (const std::string& invalid_feature_string : invalid_feature_strings) {
    std::string error_msg;
    EXPECT_EQ(cpp_defined_features->AddFeaturesFromString(invalid_feature_string, &error_msg),
              nullptr) << " Invalid feature string: '" << invalid_feature_string << "'";
    EXPECT_EQ(error_msg,
              "Specific instruction set feature(s) cannot be used when 'runtime' is used.");
  }
}

// Spaces and multiple commas are ignores in a instruction set feature string.
//
// Test that a use of spaces and multiple commas with 'default' and 'runtime'
// does not cause errors.
TEST(InstructionSetFeaturesTest, AddFeaturesFromValidStringContainingDefaultOrRuntime) {
  std::unique_ptr<const InstructionSetFeatures> cpp_defined_features(
      InstructionSetFeatures::FromCppDefines());
  std::vector<std::string> valid_feature_strings = {
    "default",
    ",,,default",
    "default,,,,",
    ",,,default,,,,",
    "default, , , ",
    " , , ,default",
    " , , ,default, , , ",
    " default , , , ",
    ",,,runtime",
    "runtime,,,,",
    ",,,runtime,,,,",
    "runtime, , , ",
    " , , ,runtime",
    " , , ,runtime, , , ",
    " runtime , , , "
  };
  for (const std::string& valid_feature_string : valid_feature_strings) {
    std::string error_msg;
    EXPECT_NE(cpp_defined_features->AddFeaturesFromString(valid_feature_string, &error_msg),
              nullptr) << " Valid feature string: '" << valid_feature_string << "'";
    EXPECT_TRUE(error_msg.empty()) << error_msg;
  }
}

// Spaces and multiple commas are ignores in a instruction set feature string.
//
// Test that a use of spaces and multiple commas without any feature names
// causes errors.
TEST(InstructionSetFeaturesTest, AddFeaturesFromInvalidStringWithoutFeatureNames) {
  std::unique_ptr<const InstructionSetFeatures> cpp_defined_features(
      InstructionSetFeatures::FromCppDefines());
  std::vector<std::string> invalid_feature_strings = {
    " ",
    "       ",
    ",",
    ",,",
    " , , ,,,,,,",
    "\t",
    "  \t     ",
    ",",
    ",,",
    " , , ,,,,,,"
  };
  for (const std::string& invalid_feature_string : invalid_feature_strings) {
    std::string error_msg;
    EXPECT_EQ(cpp_defined_features->AddFeaturesFromString(invalid_feature_string, &error_msg),
              nullptr) << " Invalid feature string: '" << invalid_feature_string << "'";
    EXPECT_EQ(error_msg, "No instruction set features specified");
  }
}

TEST(InstructionSetFeaturesTest, AddFeaturesFromStringRuntime) {
  std::unique_ptr<const InstructionSetFeatures> cpp_defined_features(
      InstructionSetFeatures::FromCppDefines());
  std::string error_msg;

  const std::unique_ptr<const InstructionSetFeatures> features =
      cpp_defined_features->AddFeaturesFromString("runtime", &error_msg);
  EXPECT_NE(features, nullptr);
  EXPECT_TRUE(error_msg.empty()) << error_msg;
  if (!InstructionSetFeatures::IsRuntimeDetectionSupported()) {
    EXPECT_TRUE(features->Equals(cpp_defined_features.get()));
  }
}

}  // namespace art
