// Copyright 2020 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "components/variations/variations_test_utils.h"

#include "base/base64.h"
#include "base/command_line.h"
#include "base/feature_list.h"
#include "components/metrics/clean_exit_beacon.h"
#include "components/metrics/metrics_pref_names.h"
#include "components/prefs/pref_service.h"
#include "components/variations/client_filterable_state.h"
#include "components/variations/field_trial_config/fieldtrial_testing_config.h"
#include "components/variations/pref_names.h"
#include "components/variations/proto/client_variations.pb.h"
#include "components/variations/variations_associated_data.h"
#include "components/variations/variations_switches.h"
#include "third_party/zlib/google/compression_utils.h"

namespace variations {
namespace {

// kTestSeed is a simple VariationsSeed containing:
// serial_number: "test"
// study: {
//   name: "UMA-Uniformity-Trial-50-Percent"
//   consistency: PERMANENT
//   experiment: {
//     name: "default"
//     probability_weight: 1
//   }
//   experiment: {
//     name: "group_01"
//     probability_weight: 1
//   }
// }

const char* kTestSeed_StudyNames[] = {"UMA-Uniformity-Trial-50-Percent"};

const char kTestSeed_Base64UncompressedData[] =
    "CgR0ZXN0Ej4KH1VNQS1Vbmlmb3JtaXR5LVRyaWFsLTUwLVBlcmNlbnQ4AUoLCgdkZWZhdWx0EA"
    "FKDAoIZ3JvdXBfMDEQAQ==";

const char kTestSeed_Base64CompressedData[] =
    "H4sIAAAAAAAA/+JiKUktLhGy45IP9XXUDc3LTMsvys0sqdQNKcpMzNE1NdANSC1KTs0rsWD04u"
    "ZiT0lNSyzNKRFg9OLh4kgvyi8tiDcwFGAEBAAA//90/JgERgAAAA==";

const char kTestSeed_Base64Signature[] =
    "MEUCIQD5AEAzk5qEuE3xOZl+xSZR15Ac1RJpsXMiou7i5W0sMAIgRn++ngh03HaMGC+Pjl9NOu"
    "Doxf83qsSwycF2PSS1nYQ=";

const char* kCrashingSeed_StudyNames[] = {"CrashingStudy"};

// kCrashingSeed is a VariationsSeed that triggers a crash for testing:
// serial_number:  "35ed2d9e354b414befdf930a734094019c0162f1"
// study:  {
//   name:  "CrashingStudy"
//   consistency:  PERMANENT
//   experiment:  {
//     name:  "EnabledLaunch"
//     probability_weight:  100
//     feature_association:  {
//       enable_feature:  "ForceFieldTrialSetupCrashForTesting"
//     }
//   }
//   experiment:  {
//     name:  "ForcedOn_ForceFieldTrialSetupCrashForTesting"
//     probability_weight:  0
//     feature_association:  {
//       forcing_feature_on:  "ForceFieldTrialSetupCrashForTesting"
//     }
//   }
//   experiment:  {
//     name:  "ForcedOff_ForceFieldTrialSetupCrashForTesting"
//     probability_weight:  0
//     feature_association:  {
//       forcing_feature_off:  "ForceFieldTrialSetupCrashForTesting"
//     }
//   }
//   filter:  {
//     min_version:  "91.*"
//     channel:  CANARY
//     channel:  DEV
//     channel:  BETA
//     channel:  STABLE
//     platform:  PLATFORM_ANDROID
//     platform:  PLATFORM_IOS
//     platform:  PLATFORM_ANDROID_WEBVIEW
//     platform:  PLATFORM_WINDOWS
//     platform:  PLATFORM_MAC
//     platform:  PLATFORM_LINUX
//     platform:  PLATFORM_CHROMEOS
//     platform:  PLATFORM_CHROMEOS_LACROS
//   }
// }
// version:  "hash/4aa56a1dc30dfc767615248d6fee29830198b276"

const char kCrashingSeed_Base64UncompressedData[] =
    "CigzNWVkMmQ5ZTM1NGI0MTRiZWZkZjkzMGE3MzQwOTQwMTljMDE2MmYxEp4CCg1DcmFzaGluZ1"
    "N0dWR5OAFKOAoNRW5hYmxlZExhdW5jaBBkYiUKI0ZvcmNlRmllbGRUcmlhbFNldHVwQ3Jhc2hG"
    "b3JUZXN0aW5nSlcKLEZvcmNlZE9uX0ZvcmNlRmllbGRUcmlhbFNldHVwQ3Jhc2hGb3JUZXN0aW"
    "5nEABiJRojRm9yY2VGaWVsZFRyaWFsU2V0dXBDcmFzaEZvclRlc3RpbmdKWAotRm9yY2VkT2Zm"
    "X0ZvcmNlRmllbGRUcmlhbFNldHVwQ3Jhc2hGb3JUZXN0aW5nEABiJSIjRm9yY2VGaWVsZFRyaW"
    "FsU2V0dXBDcmFzaEZvclRlc3RpbmdSHhIEOTEuKiAAIAEgAiADKAQoBSgGKAAoASgCKAMoCSIt"
    "aGFzaC80YWE1NmExZGMzMGRmYzc2NzYxNTI0OGQ2ZmVlMjk4MzAxOThiMjc2";

const char kCrashingSeed_Base64CompressedData[] =
    "H4sIAAAAAAAAAI3QwUvDMBTH8babwgKDsaMHKZNBEKdJk6bJWbbDEAQ30JskeS+2UKp07cF/"
    "Zn+rZfgH9Py+73P4ESpyhAwMilw6yaXDAMEIZgshmZGMG8+4ygJfnhMyf27tqayar0PXw6+"
    "O95rMt411NcKL7RtfLsCtyd3uu/W4q7CGY1vZ+oBd/"
    "3P5HA5HPHUDsH8nD5cMXpvPEf0icuubUfAH2fzDIYyVV2Pkt9vl1PDH+zRK4zRJJ3RKr+"
    "g1jWhMEzqhs9WmHPonaW2uLAcvGARfqELxPJMaVEDMjBbDotplhfoDs9NLbnoBAAA=";

const char kCrashingSeed_Base64Signature[] =
    "MEQCIEn1+VsBfNA93dxzpk+BLhdO91kMQnofxfTK5Uo8vDi8AiAnTCFCIPgEGWNOKzuKfNWn6"
    "emB6pnGWjSTbI/pvfxHnw==";

// Create mock testing config equivalent to:
// {
//   "UnitTest": [
//       {
//           "platforms": [
//               "android",
//               "android_weblayer",
//               "android_webview",
//               "chromeos",
//               "chromeos_lacros",
//               "fuchsia",
//               "ios",
//               "linux",
//               "mac",
//               "windows"
//           ],
//           "experiments": [
//               {
//                   "name": "Enabled",
//                   "params": {
//                       "x": "1"
//                   },
//                   "enable_features": [
//                       "UnitTestEnabled"
//                   ]
//               }
//           ]
//       }
//   ]
// }

const Study::Platform array_kFieldTrialConfig_platforms_0[] = {
    Study::PLATFORM_ANDROID,
    Study::PLATFORM_ANDROID_WEBLAYER,
    Study::PLATFORM_ANDROID_WEBVIEW,
    Study::PLATFORM_CHROMEOS,
    Study::PLATFORM_CHROMEOS_LACROS,
    Study::PLATFORM_FUCHSIA,
    Study::PLATFORM_IOS,
    Study::PLATFORM_LINUX,
    Study::PLATFORM_MAC,
    Study::PLATFORM_WINDOWS,
};

const char* enable_features_0[] = {"UnitTestEnabled"};
const FieldTrialTestingExperimentParams array_kFieldTrialConfig_params_0[] = {
    {
        "x",
        "1",
    },
};

const FieldTrialTestingExperiment array_kFieldTrialConfig_experiments_0[] = {
    {/*name=*/"Enabled",
     /*platforms=*/array_kFieldTrialConfig_platforms_0,
     /*platforms_size=*/10,
     /*form_factors=*/{},
     /*form_factors_size=*/0,
     /*is_low_end_device=*/absl::nullopt,
     /*min_os_version=*/nullptr,
     /*params=*/array_kFieldTrialConfig_params_0,
     /*params_size=*/1,
     /*enable_features=*/enable_features_0,
     /*enable_features_size=*/1,
     /*disable_features=*/nullptr,
     /*disable_features_size=*/0,
     /*forcing_flag=*/nullptr,
     /*override_ui_string=*/nullptr,
     /*override_ui_string_size=*/0},
};

const FieldTrialTestingStudy array_kFieldTrialConfig_studies[] = {
    {/*name=*/"UnitTest",
     /*experiments=*/array_kFieldTrialConfig_experiments_0,
     /*experiments_size=*/1},
};

}  // namespace

const SignedSeedData kTestSeedData{
    kTestSeed_StudyNames, kTestSeed_Base64UncompressedData,
    kTestSeed_Base64CompressedData, kTestSeed_Base64Signature};

const SignedSeedData kCrashingSeedData{
    kCrashingSeed_StudyNames, kCrashingSeed_Base64UncompressedData,
    kCrashingSeed_Base64CompressedData, kCrashingSeed_Base64Signature};

const SignedSeedPrefKeys kSafeSeedPrefKeys{prefs::kVariationsSafeCompressedSeed,
                                           prefs::kVariationsSafeSeedSignature};

const SignedSeedPrefKeys kRegularSeedPrefKeys{prefs::kVariationsCompressedSeed,
                                              prefs::kVariationsSeedSignature};

SignedSeedData::SignedSeedData(base::span<const char*> in_study_names,
                               const char* in_base64_uncompressed_data,
                               const char* in_base64_compressed_data,
                               const char* in_base64_signature)
    : study_names(std::move(in_study_names)),
      base64_uncompressed_data(in_base64_uncompressed_data),
      base64_compressed_data(in_base64_compressed_data),
      base64_signature(in_base64_signature) {}

SignedSeedData::~SignedSeedData() = default;

SignedSeedData::SignedSeedData(const SignedSeedData&) = default;
SignedSeedData::SignedSeedData(SignedSeedData&&) = default;
SignedSeedData& SignedSeedData::operator=(const SignedSeedData&) = default;
SignedSeedData& SignedSeedData::operator=(SignedSeedData&&) = default;

void DisableTestingConfig() {
  base::CommandLine::ForCurrentProcess()->AppendSwitch(
      switches::kDisableFieldTrialTestingConfig);
}

void EnableTestingConfig() {
  base::CommandLine::ForCurrentProcess()->AppendSwitch(
      switches::kEnableFieldTrialTestingConfig);
}

bool ExtractVariationIds(const std::string& variations,
                         std::set<VariationID>* variation_ids,
                         std::set<VariationID>* trigger_ids) {
  std::string serialized_proto;
  if (!base::Base64Decode(variations, &serialized_proto))
    return false;
  ClientVariations proto;
  if (!proto.ParseFromString(serialized_proto))
    return false;
  for (int i = 0; i < proto.variation_id_size(); ++i)
    variation_ids->insert(proto.variation_id(i));
  for (int i = 0; i < proto.trigger_variation_id_size(); ++i)
    trigger_ids->insert(proto.trigger_variation_id(i));
  return true;
}

scoped_refptr<base::FieldTrial> CreateTrialAndAssociateId(
    const std::string& trial_name,
    const std::string& default_group_name,
    IDCollectionKey key,
    VariationID id) {
  AssociateGoogleVariationID(key, trial_name, default_group_name, id);
  scoped_refptr<base::FieldTrial> trial(
      base::FieldTrialList::CreateFieldTrial(trial_name, default_group_name));
  DCHECK(trial);

  if (trial) {
    // Ensure the trial is registered under the correct key so we can look it
    // up.
    trial->Activate();
  }

  return trial;
}

void SimulateCrash(PrefService* local_state) {
  local_state->SetBoolean(metrics::prefs::kStabilityExitedCleanly, false);
  metrics::CleanExitBeacon::SkipCleanShutdownStepsForTesting();
}

void WriteSeedData(PrefService* local_state,
                   const SignedSeedData& seed_data,
                   const SignedSeedPrefKeys& pref_keys) {
  local_state->SetString(pref_keys.base64_compressed_data_key,
                         seed_data.base64_compressed_data);
  local_state->SetString(pref_keys.base64_signature_key,
                         seed_data.base64_signature);
  local_state->CommitPendingWrite();
}

bool FieldTrialListHasAllStudiesFrom(const SignedSeedData& seed_data) {
  return base::ranges::all_of(seed_data.study_names, [](const char* study) {
    return base::FieldTrialList::TrialExists(study);
  });
}

void ResetVariations() {
  testing::ClearAllVariationIDs();
  testing::ClearAllVariationParams();
}

const FieldTrialTestingConfig kTestingConfig = {
    array_kFieldTrialConfig_studies,
    1,
};

std::unique_ptr<ClientFilterableState> CreateDummyClientFilterableState() {
  auto client_state = std::make_unique<ClientFilterableState>(
      base::BindOnce([] { return false; }),
      base::BindOnce([] { return base::flat_set<uint64_t>(); }));
  client_state->locale = "en-CA";
  client_state->reference_date = base::Time::Now();
  client_state->version = base::Version("20.0.0.0");
  client_state->channel = Study::STABLE;
  client_state->form_factor = Study::PHONE;
  client_state->platform = Study::PLATFORM_ANDROID;
  return client_state;
}

MockEntropyProviders::MockEntropyProviders(
    MockEntropyProviders::Results results,
    uint32_t low_entropy_domain)
    : EntropyProviders(results.high_entropy.has_value() ? "client_id" : "",
                       {0, low_entropy_domain}),
      low_provider_(results.low_entropy),
      high_provider_(results.high_entropy.value_or(0)) {}

MockEntropyProviders::~MockEntropyProviders() = default;

const base::FieldTrial::EntropyProvider& MockEntropyProviders::low_entropy()
    const {
  return low_provider_;
}

const base::FieldTrial::EntropyProvider& MockEntropyProviders::default_entropy()
    const {
  if (default_entropy_is_high_entropy()) {
    return high_provider_;
  }
  return low_provider_;
}

}  // namespace variations
