// Copyright 2016 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.

#import "ios/chrome/app/application_delegate/metrics_mediator.h"

#include "base/mac/bind_objc_block.h"
#include "base/metrics/user_metrics_action.h"
#include "base/strings/sys_string_conversions.h"
#include "components/crash/core/common/crash_keys.h"
#include "components/metrics/metrics_pref_names.h"
#include "components/metrics/metrics_service.h"
#include "components/prefs/pref_service.h"
#import "ios/chrome/app/application_delegate/startup_information.h"
#include "ios/chrome/browser/application_context.h"
#include "ios/chrome/browser/chrome_url_constants.h"
#include "ios/chrome/browser/crash_report/breakpad_helper.h"
#import "ios/chrome/browser/crash_report/crash_report_background_uploader.h"
#include "ios/chrome/browser/experimental_flags.h"
#include "ios/chrome/browser/metrics/first_user_action_recorder.h"
#import "ios/chrome/browser/metrics/previous_session_info.h"
#import "ios/chrome/browser/net/connection_type_observer_bridge.h"
#include "ios/chrome/browser/pref_names.h"
#import "ios/chrome/browser/tabs/tab.h"
#import "ios/chrome/browser/tabs/tab_model.h"
#import "ios/chrome/browser/ui/main/browser_view_information.h"
#include "ios/chrome/common/app_group/app_group_metrics_mainapp.h"
#include "ios/public/provider/chrome/browser/chrome_browser_provider.h"
#include "ios/public/provider/chrome/browser/distribution/app_distribution_provider.h"
#include "ios/web/public/web_thread.h"
#include "url/gurl.h"

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

namespace {
// The amount of time (in seconds) between two background fetch calls.
// TODO(crbug.com/496172): Re-enable background fetch.
const NSTimeInterval kBackgroundFetchIntervalDelay =
    UIApplicationBackgroundFetchIntervalNever;
// The amount of time (in seconds) to wait for the user to start a new task.
const NSTimeInterval kFirstUserActionTimeout = 30.0;
}  // namespace

namespace metrics_mediator {
NSString* const kAppEnteredBackgroundDateKey = @"kAppEnteredBackgroundDate";
}  // namespace metrics_mediator_constants

using metrics_mediator::kAppEnteredBackgroundDateKey;

@interface MetricsMediator ()<CRConnectionTypeObserverBridge> {
  // Whether or not the crash reports present at startup have been processed to
  // determine if the last app lifetime ended in an OOM crash.
  BOOL _hasProcessedCrashReportsPresentAtStartup;

  // Observer for the connection type.  Contains a valid object only if the
  // metrics setting is set to wifi-only.
  std::unique_ptr<ConnectionTypeObserverBridge> connectionTypeObserverBridge_;
}

// Starts or stops metrics recording and/or uploading.
- (void)setMetricsEnabled:(BOOL)enabled withUploading:(BOOL)allowUploading;
// Sets variables needed by the app_group application to collect UMA data.
// Process the pending logs produced by extensions.
// Called on start (cold and warm) and UMA settings change to update the
// collecting settings in extensions.
- (void)setAppGroupMetricsEnabled:(BOOL)enabled;
// Processes crash reports present at startup.
- (void)processCrashReportsPresentAtStartup;
// Starts or stops crash recording and/or uploading.
- (void)setBreakpadEnabled:(BOOL)enabled withUploading:(BOOL)allowUploading;
// Starts or stops watching for wwan events.
- (void)setWatchWWANEnabled:(BOOL)enabled;
// Enable/disable transmission of accumulated logs and crash reports (dumps).
- (void)setReporting:(BOOL)enableReporting;
// Enable/Disable uploading crash reports.
- (void)setBreakpadUploadingEnabled:(BOOL)enableUploading;
// Returns YES if the metrics are enabled and the reporting is wifi-only.
- (BOOL)isMetricsReportingEnabledWifiOnly;
// Update metrics prefs on a permission (opt-in/out) change. When opting out,
// this clears various client ids. When opting in, this resets saving crash
// prefs, so as not to trigger upload of various stale data.
// Mirrors the function in metrics_reporting_state.cc.
- (void)updateMetricsPrefsOnPermissionChange:(BOOL)enabled;
// Logs the number of tabs with UMAHistogramCount100 and allows testing.
+ (void)recordNumTabAtStartup:(int)numTabs;
// Logs the number of tabs with UMAHistogramCount100 and allows testing.
+ (void)recordNumTabAtResume:(int)numTabs;

@end

@implementation MetricsMediator

#pragma mark - Public methods.

+ (void)logStartupDuration:(id<StartupInformation>)startupInformation {
  if (![startupInformation isColdStart])
    return;

  base::TimeDelta startDuration =
      base::TimeTicks::Now() - [startupInformation appLaunchTime];
  if ([startupInformation startupParameters]) {
    UMA_HISTOGRAM_TIMES("Startup.ColdStartWithExternalURLTime", startDuration);
  } else {
    UMA_HISTOGRAM_TIMES("Startup.ColdStartWithoutExternalURLTime",
                        startDuration);
  }
}

+ (void)logDateInUserDefaults {
  [[NSUserDefaults standardUserDefaults]
      setObject:[NSDate date]
         forKey:metrics_mediator::kAppEnteredBackgroundDateKey];
}

+ (void)logLaunchMetricsWithStartupInformation:
            (id<StartupInformation>)startupInformation
                        browserViewInformation:
                            (id<BrowserViewInformation>)browserViewInformation {
  int numTabs = static_cast<int>([[browserViewInformation mainTabModel] count]);
  if (startupInformation.isColdStart) {
    [self recordNumTabAtStartup:numTabs];
  } else {
    [self recordNumTabAtResume:numTabs];
  }

  if (UIAccessibilityIsVoiceOverRunning()) {
    base::RecordAction(
        base::UserMetricsAction("MobileVoiceOverActiveOnLaunch"));
  }

  // Create the first user action recorder and schedule a task to expire it
  // after some timeout. If unable to determine the last time the app entered
  // the background (i.e. either first run or restore after crash), don't bother
  // recording the first user action since fresh start wouldn't be triggered.
  NSDate* lastAppClose = [[NSUserDefaults standardUserDefaults]
      objectForKey:kAppEnteredBackgroundDateKey];
  if (lastAppClose) {
    NSTimeInterval interval = -[lastAppClose timeIntervalSinceNow];
    [startupInformation
        activateFirstUserActionRecorderWithBackgroundTime:interval];
    GURL ntpUrl = GURL(kChromeUINewTabURL);

    Tab* currentTab = [[browserViewInformation currentTabModel] currentTab];
    if (currentTab && [currentTab url] == ntpUrl) {
      startupInformation.firstUserActionRecorder->RecordStartOnNTP();
      [startupInformation resetFirstUserActionRecorder];
    } else {
      [startupInformation
          expireFirstUserActionRecorderAfterDelay:kFirstUserActionTimeout];
    }
    // Remove the value so it's not reused if the app crashes.
    [[NSUserDefaults standardUserDefaults]
        removeObjectForKey:kAppEnteredBackgroundDateKey];
  }
}

- (void)updateMetricsStateBasedOnPrefsUserTriggered:(BOOL)isUserTriggered {
  BOOL optIn = [self areMetricsEnabled];
  BOOL allowUploading = [self isUploadingEnabled];
  BOOL wifiOnly = GetApplicationContext()->GetLocalState()->GetBoolean(
      prefs::kMetricsReportingWifiOnly);

  if (isUserTriggered)
    [self updateMetricsPrefsOnPermissionChange:optIn];
  [self setMetricsEnabled:optIn withUploading:allowUploading];
  [self setBreakpadEnabled:optIn withUploading:allowUploading];
  [self setWatchWWANEnabled:(optIn && wifiOnly)];
}

- (BOOL)areMetricsEnabled {
// If this if-def changes, it needs to be changed in
// IOSChromeMainParts::IsMetricsReportingEnabled and settings_egtest.mm.
#if defined(GOOGLE_CHROME_BUILD)
  BOOL optIn = GetApplicationContext()->GetLocalState()->GetBoolean(
      metrics::prefs::kMetricsReportingEnabled);
#else
  // If a startup crash has been requested, then pretend that metrics have been
  // enabled, so that the app will go into recovery mode.
  BOOL optIn = experimental_flags::IsStartupCrashEnabled();
#endif
  return optIn;
}

- (BOOL)isUploadingEnabled {
  BOOL optIn = [self areMetricsEnabled];
  BOOL wifiOnly = GetApplicationContext()->GetLocalState()->GetBoolean(
      prefs::kMetricsReportingWifiOnly);
  BOOL allowUploading = optIn;
  if (optIn && wifiOnly) {
    BOOL usingWWAN = net::NetworkChangeNotifier::IsConnectionCellular(
        net::NetworkChangeNotifier::GetConnectionType());
    allowUploading = !usingWWAN;
  }
  return allowUploading;
}

#pragma mark - Internal methods.

- (void)setMetricsEnabled:(BOOL)enabled withUploading:(BOOL)allowUploading {
  metrics::MetricsService* metrics =
      GetApplicationContext()->GetMetricsService();
  DCHECK(metrics);
  if (!metrics)
    return;
  if (enabled) {
    [[UIApplication sharedApplication]
        setMinimumBackgroundFetchInterval:kBackgroundFetchIntervalDelay];
    if (!metrics->recording_active())
      metrics->Start();

    if (allowUploading)
      metrics->EnableReporting();
    else
      metrics->DisableReporting();
  } else {
    if (metrics->recording_active())
      metrics->Stop();
    [[UIApplication sharedApplication]
        setMinimumBackgroundFetchInterval:
            UIApplicationBackgroundFetchIntervalNever];
  }
}

- (void)setAppGroupMetricsEnabled:(BOOL)enabled {
  metrics::MetricsService* metrics =
      GetApplicationContext()->GetMetricsService();
  if (enabled) {
    PrefService* prefs = GetApplicationContext()->GetLocalState();
    NSString* brandCode =
        base::SysUTF8ToNSString(ios::GetChromeBrowserProvider()
                                    ->GetAppDistributionProvider()
                                    ->GetDistributionBrandCode());
    app_group::main_app::EnableMetrics(
        base::SysUTF8ToNSString(metrics->GetClientId()), brandCode,
        prefs->GetInt64(metrics::prefs::kInstallDate),
        prefs->GetInt64(metrics::prefs::kMetricsReportingEnabledTimestamp));
  } else {
    app_group::main_app::DisableMetrics();
  }

  // If metrics are enabled, process the logs. Otherwise, just delete them.
  app_group::ProceduralBlockWithData callback;
  if (enabled) {
    callback = [^(NSData* log_content) {
      std::string log(static_cast<const char*>([log_content bytes]),
                      static_cast<size_t>([log_content length]));
      web::WebThread::PostTask(web::WebThread::UI, FROM_HERE,
                               base::BindBlockArc(^{
                                 metrics->PushExternalLog(log);
                               }));
    } copy];
  }

  web::WebThread::PostTask(
      web::WebThread::FILE, FROM_HERE,
      base::Bind(&app_group::main_app::ProcessPendingLogs, callback));
}

- (void)processCrashReportsPresentAtStartup {
  _hasProcessedCrashReportsPresentAtStartup = YES;

  breakpad_helper::GetCrashReportCount(^(int crashReportCount) {
    [[CrashReportBackgroundUploader sharedInstance]
        setHasPendingCrashReportsToUploadAtStartup:(crashReportCount > 0)];
  });
}

- (void)setBreakpadEnabled:(BOOL)enabled withUploading:(BOOL)allowUploading {
  if (enabled) {
    breakpad_helper::SetEnabled(true);

    // Do some processing of the crash reports present at startup. Note that
    // this processing must be done before uploading is enabled because once
    // uploading starts the number of crash reports present will begin to
    // decrease as they are uploaded. The ordering is ensured here because both
    // the crash report processing and the upload enabling are handled by
    // posting blocks to a single |dispath_queue_t| in BreakpadController.
    if (!_hasProcessedCrashReportsPresentAtStartup && allowUploading) {
      [self processCrashReportsPresentAtStartup];
    }
    [self setBreakpadUploadingEnabled:(![[PreviousSessionInfo sharedInstance]
                                           isFirstSessionAfterUpgrade] &&
                                       allowUploading)];
  } else {
    breakpad_helper::SetEnabled(false);
  }
}

- (void)setWatchWWANEnabled:(BOOL)enabled {
  if (!enabled) {
    connectionTypeObserverBridge_.reset();
    return;
  }

  if (!connectionTypeObserverBridge_) {
    connectionTypeObserverBridge_.reset(new ConnectionTypeObserverBridge(self));
  }
}

- (void)updateMetricsPrefsOnPermissionChange:(BOOL)enabled {
  // TODO(crbug.com/635669): Consolidate with metrics_reporting_state.cc
  // function.
  metrics::MetricsService* metrics =
      GetApplicationContext()->GetMetricsService();
  DCHECK(metrics);
  if (!metrics)
    return;
  if (enabled) {
    // When a user opts in to the metrics reporting service, the previously
    // collected data should be cleared to ensure that nothing is reported
    // before a user opts in and all reported data is accurate.
    if (!metrics->recording_active())
      metrics->ClearSavedStabilityMetrics();
  } else {
    // Clear the client id pref when opting out.
    // Note: Clearing client id will not affect the running state (e.g. field
    // trial randomization), as the pref is only read on startup.
    GetApplicationContext()->GetLocalState()->ClearPref(
        metrics::prefs::kMetricsClientID);
    GetApplicationContext()->GetLocalState()->ClearPref(
        metrics::prefs::kMetricsReportingEnabledTimestamp);
    crash_keys::ClearMetricsClientId();
  }
}

+ (void)disableReporting {
  breakpad_helper::SetUploadingEnabled(false);
  metrics::MetricsService* metrics =
      GetApplicationContext()->GetMetricsService();
  DCHECK(metrics);
  metrics->DisableReporting();
}

+ (void)applicationDidEnterBackground:(NSInteger)memoryWarningCount {
  base::RecordAction(base::UserMetricsAction("MobileEnteredBackground"));
  UMA_HISTOGRAM_COUNTS_100("MemoryWarning.OccurrencesPerSession",
                           memoryWarningCount);
}

#pragma mark - CRConnectionTypeObserverBridge implementation

- (void)connectionTypeChanged:(net::NetworkChangeNotifier::ConnectionType)type {
  BOOL wwanEnabled = net::NetworkChangeNotifier::IsConnectionCellular(type);
  // Currently the MainController only cares about WWAN state for the metrics
  // reporting preference.  If it's disabled, or the wifi-only preference is
  // not set, we don't care.  In fact, we should not even be getting this call.
  DCHECK([self isMetricsReportingEnabledWifiOnly]);
  // |wwanEnabled| is true if a cellular connection such as EDGE or GPRS is
  // used. Otherwise, either there is no connection available, or another link
  // (such as WiFi) is used.
  if (wwanEnabled) {
    // If WWAN mode is on, wifi-only prefs should be disabled.
    // For the crash reporter, we still want to record the crashes.
    [self setBreakpadUploadingEnabled:NO];
    [self setReporting:NO];
  } else if ([self areMetricsEnabled]) {
    // Double-check that the metrics reporting preference is enabled.
    if (![[PreviousSessionInfo sharedInstance] isFirstSessionAfterUpgrade])
      [self setBreakpadUploadingEnabled:YES];
    [self setReporting:YES];
  }
}

#pragma mark - interfaces methods

+ (void)recordNumTabAtStartup:(int)numTabs {
  UMA_HISTOGRAM_COUNTS_100("Tabs.CountAtStartup", numTabs);
}

+ (void)recordNumTabAtResume:(int)numTabs {
  UMA_HISTOGRAM_COUNTS_100("Tabs.CountAtResume", numTabs);
}

- (void)setBreakpadUploadingEnabled:(BOOL)enableUploading {
  breakpad_helper::SetUploadingEnabled(enableUploading);
}

- (void)setReporting:(BOOL)enableReporting {
  if (enableReporting) {
    GetApplicationContext()->GetMetricsService()->EnableReporting();
  } else {
    GetApplicationContext()->GetMetricsService()->DisableReporting();
  }
}

- (BOOL)isMetricsReportingEnabledWifiOnly {
  return GetApplicationContext()->GetLocalState()->GetBoolean(
             metrics::prefs::kMetricsReportingEnabled) &&
         GetApplicationContext()->GetLocalState()->GetBoolean(
             prefs::kMetricsReportingWifiOnly);
}

@end
