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

// Implementation of about_flags for iOS that sets flags based on experimental
// settings.

#include "ios/chrome/browser/about_flags.h"

#include <stddef.h>
#include <stdint.h>
#import <UIKit/UIKit.h>

#include "base/bind.h"
#include "base/command_line.h"
#include "base/logging.h"
#include "base/macros.h"
#include "base/memory/singleton.h"
#include "base/strings/stringprintf.h"
#include "base/strings/sys_string_conversions.h"
#include "base/sys_info.h"
#include "base/task_scheduler/switches.h"
#include "components/dom_distiller/core/dom_distiller_switches.h"
#include "components/flags_ui/feature_entry.h"
#include "components/flags_ui/feature_entry_macros.h"
#include "components/flags_ui/flags_storage.h"
#include "components/flags_ui/flags_ui_switches.h"
#include "components/ntp_tiles/switches.h"
#include "components/reading_list/core/reading_list_switches.h"
#include "components/strings/grit/components_strings.h"
#include "components/sync/driver/sync_driver_switches.h"
#include "google_apis/gaia/gaia_switches.h"
#include "ios/chrome/browser/chrome_switches.h"
#include "ios/chrome/grit/ios_strings.h"
#include "ios/web/public/user_agent.h"
#include "ios/web/public/web_view_creation_util.h"

#if !defined(OFFICIAL_BUILD)
#include "components/variations/variations_switches.h"
#endif

#if !defined(__has_feature) || !__has_feature(objc_arc)
#error "This file requires ARC support."
#endif

namespace {
// To add a new entry, add to the end of kFeatureEntries. There are two
// distinct types of entries:
// . SINGLE_VALUE: entry is either on or off. Use the SINGLE_VALUE_TYPE
//   macro for this type supplying the command line to the macro.
// . MULTI_VALUE: a list of choices, the first of which should correspond to a
//   deactivated state for this lab (i.e. no command line option).  To specify
//   this type of entry use the macro MULTI_VALUE_TYPE supplying it the
//   array of choices.
// See the documentation of FeatureEntry for details on the fields.
//
// When adding a new choice, add it to the end of the list.
const flags_ui::FeatureEntry kFeatureEntries[] = {
    {"contextual-search", IDS_IOS_FLAGS_CONTEXTUAL_SEARCH,
     IDS_IOS_FLAGS_CONTEXTUAL_SEARCH_DESCRIPTION, flags_ui::kOsIos,
     ENABLE_DISABLE_VALUE_TYPE(switches::kEnableContextualSearch,
                               switches::kDisableContextualSearch)},
    {"ios-physical-web", IDS_IOS_FLAGS_PHYSICAL_WEB,
     IDS_IOS_FLAGS_PHYSICAL_WEB_DESCRIPTION, flags_ui::kOsIos,
     ENABLE_DISABLE_VALUE_TYPE(switches::kEnableIOSPhysicalWeb,
                               switches::kDisableIOSPhysicalWeb)},
    {"browser-task-scheduler", IDS_IOS_FLAGS_BROWSER_TASK_SCHEDULER_NAME,
     IDS_IOS_FLAGS_BROWSER_TASK_SCHEDULER_DESCRIPTION, flags_ui::kOsIos,
     ENABLE_DISABLE_VALUE_TYPE(switches::kEnableBrowserTaskScheduler,
                               switches::kDisableBrowserTaskScheduler)},
};

// Add all switches from experimental flags to |command_line|.
void AppendSwitchesFromExperimentalSettings(base::CommandLine* command_line) {
  NSUserDefaults* defaults = [NSUserDefaults standardUserDefaults];

  // GAIA staging environment.
  NSString* kGAIAEnvironment = @"GAIAEnvironment";
  NSString* gaia_environment = [defaults stringForKey:kGAIAEnvironment];
  if ([gaia_environment isEqualToString:@"Staging"]) {
    command_line->AppendSwitchASCII(switches::kGoogleApisUrl,
                                    GOOGLE_STAGING_API_URL);
    command_line->AppendSwitchASCII(switches::kLsoUrl, GOOGLE_STAGING_LSO_URL);
  } else if ([gaia_environment isEqualToString:@"Test"]) {
    command_line->AppendSwitchASCII(switches::kGaiaUrl, GOOGLE_TEST_OAUTH_URL);
    command_line->AppendSwitchASCII(switches::kGoogleApisUrl,
                                    GOOGLE_TEST_API_URL);
    command_line->AppendSwitchASCII(switches::kLsoUrl, GOOGLE_TEST_LSO_URL);
    command_line->AppendSwitchASCII(switches::kSyncServiceURL,
                                    GOOGLE_TEST_SYNC_URL);
    command_line->AppendSwitchASCII(switches::kOAuth2ClientID,
                                    GOOGLE_TEST_OAUTH_CLIENT_ID);
    command_line->AppendSwitchASCII(switches::kOAuth2ClientSecret,
                                    GOOGLE_TEST_OAUTH_CLIENT_SECRET);
  }

  // Populate command line flag for the Tab Switcher experiment from the
  // configuration plist.
  NSString* enableTabSwitcher = [defaults stringForKey:@"EnableTabSwitcher"];
  if ([enableTabSwitcher isEqualToString:@"Enabled"]) {
    command_line->AppendSwitch(switches::kEnableTabSwitcher);
  } else if ([enableTabSwitcher isEqualToString:@"Disabled"]) {
    command_line->AppendSwitch(switches::kDisableTabSwitcher);
  }

  // Populate command line flag for the SnapshotLRUCache experiment from the
  // configuration plist.
  NSString* enableLRUSnapshotCache =
      [defaults stringForKey:@"SnapshotLRUCache"];
  if ([enableLRUSnapshotCache isEqualToString:@"Enabled"]) {
    command_line->AppendSwitch(switches::kEnableLRUSnapshotCache);
  } else if ([enableLRUSnapshotCache isEqualToString:@"Disabled"]) {
    command_line->AppendSwitch(switches::kDisableLRUSnapshotCache);
  }

  // Populate command line flag for the AllBookmarks from the
  // configuration plist.
  NSString* enableAllBookmarks = [defaults stringForKey:@"AllBookmarks"];
  if ([enableAllBookmarks isEqualToString:@"Enabled"]) {
    command_line->AppendSwitch(switches::kEnableAllBookmarksView);
  } else if ([enableAllBookmarks isEqualToString:@"Disabled"]) {
    command_line->AppendSwitch(switches::kDisableAllBookmarksView);
  }

  // Populate command line flags from PasswordGenerationEnabled.
  NSString* enablePasswordGenerationValue =
      [defaults stringForKey:@"PasswordGenerationEnabled"];
  if ([enablePasswordGenerationValue isEqualToString:@"Enabled"]) {
    command_line->AppendSwitch(switches::kEnableIOSPasswordGeneration);
  } else if ([enablePasswordGenerationValue isEqualToString:@"Disabled"]) {
    command_line->AppendSwitch(switches::kDisableIOSPasswordGeneration);
  }

  // Populate command line flags from PhysicalWebEnabled.
  NSString* enablePhysicalWebValue =
      [defaults stringForKey:@"PhysicalWebEnabled"];
  if ([enablePhysicalWebValue isEqualToString:@"Enabled"]) {
    command_line->AppendSwitch(switches::kEnableIOSPhysicalWeb);
  } else if ([enablePhysicalWebValue isEqualToString:@"Disabled"]) {
    command_line->AppendSwitch(switches::kDisableIOSPhysicalWeb);
  }

  // Web page replay flags.
  BOOL webPageReplayEnabled = [defaults boolForKey:@"WebPageReplayEnabled"];
  NSString* webPageReplayProxy =
      [defaults stringForKey:@"WebPageReplayProxyAddress"];
  if (webPageReplayEnabled && [webPageReplayProxy length]) {
    command_line->AppendSwitch(switches::kIOSIgnoreCertificateErrors);
    // 80 and 443 are the default ports from web page replay.
    command_line->AppendSwitchASCII(switches::kIOSTestingFixedHttpPort, "80");
    command_line->AppendSwitchASCII(switches::kIOSTestingFixedHttpsPort, "443");
    command_line->AppendSwitchASCII(
        switches::kIOSHostResolverRules,
        "MAP * " + base::SysNSStringToUTF8(webPageReplayProxy));
  }

  if ([defaults boolForKey:@"EnableCredentialManagement"])
    command_line->AppendSwitch(switches::kEnableCredentialManagerAPI);

  NSString* autoReloadEnabledValue =
      [defaults stringForKey:@"AutoReloadEnabled"];
  if ([autoReloadEnabledValue isEqualToString:@"Enabled"]) {
    command_line->AppendSwitch(switches::kEnableOfflineAutoReload);
  } else if ([autoReloadEnabledValue isEqualToString:@"Disabled"]) {
    command_line->AppendSwitch(switches::kDisableOfflineAutoReload);
  }

  // Populate command line flags from EnableFastWebScrollViewInsets.
  NSString* enableFastWebScrollViewInsets =
      [defaults stringForKey:@"EnableFastWebScrollViewInsets"];
  if ([enableFastWebScrollViewInsets isEqualToString:@"Enabled"]) {
    command_line->AppendSwitch(switches::kEnableIOSFastWebScrollViewInsets);
  } else if ([enableFastWebScrollViewInsets isEqualToString:@"Disabled"]) {
    command_line->AppendSwitch(switches::kDisableIOSFastWebScrollViewInsets);
  }

  // Populate command line flags from ReaderModeEnabled.
  if ([defaults boolForKey:@"ReaderModeEnabled"]) {
    command_line->AppendSwitch(switches::kEnableReaderModeToolbarIcon);

    // Populate command line from ReaderMode Heuristics detection.
    NSString* readerModeDetectionHeuristics =
        [defaults stringForKey:@"ReaderModeDetectionHeuristics"];
    if (!readerModeDetectionHeuristics) {
      command_line->AppendSwitchASCII(
          switches::kReaderModeHeuristics,
          switches::reader_mode_heuristics::kOGArticle);
    } else if ([readerModeDetectionHeuristics isEqualToString:@"AdaBoost"]) {
      command_line->AppendSwitchASCII(
          switches::kReaderModeHeuristics,
          switches::reader_mode_heuristics::kAdaBoost);
    } else {
      DCHECK([readerModeDetectionHeuristics isEqualToString:@"Off"]);
      command_line->AppendSwitchASCII(switches::kReaderModeHeuristics,
                                      switches::reader_mode_heuristics::kNone);
    }
  }

  // Populate command line flags from EnablePopularSites.
  NSString* EnablePopularSites = [defaults stringForKey:@"EnablePopularSites"];
  if ([EnablePopularSites isEqualToString:@"Enabled"]) {
    command_line->AppendSwitch(ntp_tiles::switches::kEnableNTPPopularSites);
  } else if ([EnablePopularSites isEqualToString:@"Disabled"]) {
    command_line->AppendSwitch(ntp_tiles::switches::kDisableNTPPopularSites);
  }

  // Set the UA flag if UseMobileSafariUA is enabled.
  if ([defaults boolForKey:@"UseMobileSafariUA"]) {
    // Safari uses "Vesion/", followed by the OS version excluding bugfix, where
    // Chrome puts its product token.
    int32_t major = 0;
    int32_t minor = 0;
    int32_t bugfix = 0;
    base::SysInfo::OperatingSystemVersionNumbers(&major, &minor, &bugfix);
    std::string product = base::StringPrintf("Version/%d.%d", major, minor);

    command_line->AppendSwitchASCII(switches::kUserAgent,
                                    web::BuildUserAgentFromProduct(product));
  }

  // Populate command line flags from QRScanner.
  if ([defaults boolForKey:@"DisableQRCodeReader"]) {
    command_line->AppendSwitch(switches::kDisableQRScanner);
  } else {
    command_line->AppendSwitch(switches::kEnableQRScanner);
  }

  // Populate command line flag for the Payment Request API.
  NSString* enable_payment_request =
      [defaults stringForKey:@"EnablePaymentRequest"];
  if ([enable_payment_request isEqualToString:@"Enabled"]) {
    command_line->AppendSwitch(switches::kEnablePaymentRequest);
  } else if ([enable_payment_request isEqualToString:@"Disabled"]) {
    command_line->AppendSwitch(switches::kDisablePaymentRequest);
  }

  // Populate command line flags from Reading List.
  if ([defaults boolForKey:@"EnableReadingList"]) {
    command_line->AppendSwitch(reading_list::switches::kEnableReadingList);
  } else {
    command_line->AppendSwitch(reading_list::switches::kDisableReadingList);
  }

  // Populate command line flag for Spotlight Actions.
  if ([defaults boolForKey:@"DisableSpotlightActions"]) {
    command_line->AppendSwitch(switches::kDisableSpotlightActions);
  }

  // Populate command line flag for the Rename "Save Image" to "Download Image"
  // experiment.
  NSString* enableDownloadRenaming =
      [defaults stringForKey:@"EnableDownloadRenaming"];
  if ([enableDownloadRenaming isEqualToString:@"Enabled"]) {
    command_line->AppendSwitch(switches::kEnableDownloadImageRenaming);
  } else if ([enableDownloadRenaming isEqualToString:@"Disabled"]) {
    command_line->AppendSwitch(switches::kDisableDownloadImageRenaming);
  }

  // Freeform commandline flags.  These are added last, so that any flags added
  // earlier in this function take precedence.
  if ([defaults boolForKey:@"EnableFreeformCommandLineFlags"]) {
    base::CommandLine::StringVector flags;
    // Append an empty "program" argument.
    flags.push_back("");

    // The number of flags corresponds to the number of text fields in
    // Experimental.plist.
    const int kNumFreeformFlags = 5;
    for (int i = 1; i <= kNumFreeformFlags; ++i) {
      NSString* key =
          [NSString stringWithFormat:@"FreeformCommandLineFlag%d", i];
      NSString* flag = [defaults stringForKey:key];
      if ([flag length]) {
        flags.push_back(base::SysNSStringToUTF8(flag));
      }
    }

    base::CommandLine temp_command_line(flags);
    command_line->AppendArguments(temp_command_line, false);
  }
}

bool SkipConditionalFeatureEntry(const flags_ui::FeatureEntry& entry) {
  return false;
}

class FlagsStateSingleton {
 public:
  FlagsStateSingleton()
      : flags_state_(kFeatureEntries, arraysize(kFeatureEntries)) {}
  ~FlagsStateSingleton() {}

  static FlagsStateSingleton* GetInstance() {
    return base::Singleton<FlagsStateSingleton>::get();
  }

  static flags_ui::FlagsState* GetFlagsState() {
    return &GetInstance()->flags_state_;
  }

 private:
  flags_ui::FlagsState flags_state_;

  DISALLOW_COPY_AND_ASSIGN(FlagsStateSingleton);
};
}  // namespace

void ConvertFlagsToSwitches(flags_ui::FlagsStorage* flags_storage,
                            base::CommandLine* command_line) {
  FlagsStateSingleton::GetFlagsState()->ConvertFlagsToSwitches(
      flags_storage, command_line, flags_ui::kAddSentinels,
      switches::kEnableIOSFeatures, switches::kDisableIOSFeatures);
  AppendSwitchesFromExperimentalSettings(command_line);
}

std::vector<std::string> RegisterAllFeatureVariationParameters(
    flags_ui::FlagsStorage* flags_storage,
    base::FeatureList* feature_list) {
  return FlagsStateSingleton::GetFlagsState()
      ->RegisterAllFeatureVariationParameters(flags_storage, feature_list);
}

void GetFlagFeatureEntries(flags_ui::FlagsStorage* flags_storage,
                           flags_ui::FlagAccess access,
                           base::ListValue* supported_entries,
                           base::ListValue* unsupported_entries) {
  FlagsStateSingleton::GetFlagsState()->GetFlagFeatureEntries(
      flags_storage, access, supported_entries, unsupported_entries,
      base::Bind(&SkipConditionalFeatureEntry));
}

void SetFeatureEntryEnabled(flags_ui::FlagsStorage* flags_storage,
                            const std::string& internal_name,
                            bool enable) {
  FlagsStateSingleton::GetFlagsState()->SetFeatureEntryEnabled(
      flags_storage, internal_name, enable);
}

void ResetAllFlags(flags_ui::FlagsStorage* flags_storage) {
  FlagsStateSingleton::GetFlagsState()->ResetAllFlags(flags_storage);
}

namespace testing {

const flags_ui::FeatureEntry* GetFeatureEntries(size_t* count) {
  *count = arraysize(kFeatureEntries);
  return kFeatureEntries;
}

}  // namespace testing
