// Copyright 2013 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/browser/geolocation/omnibox_geolocation_controller.h"

#import <CoreLocation/CoreLocation.h>
#import <UIKit/UIKit.h>

#include <string>

#import "base/ios/weak_nsobject.h"
#include "base/logging.h"
#include "base/mac/scoped_nsobject.h"
#include "base/metrics/histogram_macros.h"
#include "base/version.h"
#include "components/google/core/browser/google_util.h"
#include "components/version_info/version_info.h"
#include "ios/chrome/browser/browser_state/chrome_browser_state.h"
#import "ios/chrome/browser/geolocation/CLLocation+OmniboxGeolocation.h"
#import "ios/chrome/browser/geolocation/CLLocation+XGeoHeader.h"
#import "ios/chrome/browser/geolocation/location_manager.h"
#import "ios/chrome/browser/geolocation/omnibox_geolocation_authorization_alert.h"
#import "ios/chrome/browser/geolocation/omnibox_geolocation_config.h"
#import "ios/chrome/browser/geolocation/omnibox_geolocation_controller+Testing.h"
#import "ios/chrome/browser/geolocation/omnibox_geolocation_local_state.h"
#import "ios/chrome/browser/tabs/tab.h"
#include "ios/web/public/navigation_item.h"
#import "ios/web/public/navigation_manager.h"
#include "url/gurl.h"

namespace {

// Values for the histogram that records whether we sent the X-Geo header for
// an Omnibox query or why we did not do so. These match the definition of
// GeolocationHeaderSentOrNot in Chromium
// src-internal/tools/histograms/histograms.xml.
typedef enum {
  // The user disabled location for Google.com (not used by Chrome iOS).
  kHeaderStateNotSentAuthorizationGoogleDenied = 0,
  // The user has not yet determined Chrome's access to the current device
  // location or Chrome's use of geolocation for Omnibox queries.
  kHeaderStateNotSentAuthorizationNotDetermined,
  // The current device location is not available.
  kHeaderStateNotSentLocationNotAvailable,
  // The current device location is stale.
  kHeaderStateNotSentLocationStale,
  // The X-Geo header was sent.
  kHeaderStateSent,
  // The user denied Chrome from accessing the current device location.
  kHeaderStateNotSentAuthorizationChromeDenied,
  // The user denied Chrome from using geolocation for Omnibox queries.
  kHeaderStateNotSentAuthorizationOmniboxDenied,
  // The user's Google search domain is not whitelisted.
  kHeaderStateNotSentDomainNotWhitelisted,
  // The number of possible of HeaderState values to report.
  kHeaderStateCount,
} HeaderState;

// Values for the histograms that record the user's action when prompted to
// authorize the use of location by Chrome. These match the definition of
// GeolocationAuthorizationAction in Chromium
// src-internal/tools/histograms/histograms.xml.
typedef enum {
  // The user authorized use of location.
  kAuthorizationActionAuthorized = 0,
  // The user permanently denied use of location (Don't Allow).
  kAuthorizationActionPermanentlyDenied,
  // The user denied use of location at this prompt (Not Now).
  kAuthorizationActionDenied,
  // The number of possible AuthorizationAction values to report.
  kAuthorizationActionCount,
} AuthorizationAction;

// Name of the histogram recording HeaderState.
const char* const kGeolocationHeaderSentOrNotHistogram =
    "Geolocation.HeaderSentOrNot";

// Name of the histogram recording location acquisition time.
const char* const kOmniboxQueryGeolocationAcquisitionTimeHistogram =
    "Omnibox.QueryGeolocationAcquisitionTime";

// Name of the histogram recording estimated location accuracy.
const char* const kOmniboxQueryGeolocationHorizontalAccuracyHistogram =
    "Omnibox.QueryGeolocationHorizontalAccuracy";

// Name of the histogram recording AuthorizationAction for an existing user.
const char* const kGeolocationAuthorizationActionExistingUser =
    "Geolocation.AuthorizationActionExistingUser";

// Name of the histogram recording AuthorizationAction for a new user.
const char* const kGeolocationAuthorizationActionNewUser =
    "Geolocation.AuthorizationActionNewUser";

}  // anonymous namespace

@interface OmniboxGeolocationController ()<
    LocationManagerDelegate,
    OmniboxGeolocationAuthorizationAlertDelegate> {
  base::scoped_nsobject<OmniboxGeolocationLocalState> localState_;
  base::scoped_nsobject<LocationManager> locationManager_;
  base::scoped_nsobject<OmniboxGeolocationAuthorizationAlert>
      authorizationAlert_;
  base::WeakNSObject<Tab> weakTabToReload_;

  // Records whether we have deliberately presented the system prompt, so that
  // we can record the user's action in
  // locationManagerDidChangeAuthorizationStatus:.
  BOOL systemPrompt_;

  // Records whether we are prompting for a new user, so that we can record the
  // user's action to the right histogram (either
  // kGeolocationAuthorizationActionExistingUser or
  // kGeolocationAuthorizationActionNewUser).
  BOOL newUser_;
}

// Boolean value indicating whether geolocation is enabled for Omnibox queries.
@property(nonatomic, readonly) BOOL enabled;

// Convenience property lazily initializes |localState_|.
@property(nonatomic, readonly) OmniboxGeolocationLocalState* localState;

// Convenience property lazily initializes |locationManager_|.
@property(nonatomic, readonly) LocationManager* locationManager;

// Returns YES if and only if |url| and |transition| specify an Omnibox query
// that is eligible for geolocation.
- (BOOL)URLIsEligibleQueryURL:(const GURL&)url
                   transition:(ui::PageTransition)transition;

// Returns YES if and only if |url| and |transition| specify an Omnibox query.
//
// Note: URLIsQueryURL:transition: is more liberal than
// URLIsEligibleQueryURL:transition:. Use URLIsEligibleQueryURL:transition: and
// not URLIsQueryURL:transition: to test Omnibox query URLs with respect to
// sending location to Google.
- (BOOL)URLIsQueryURL:(const GURL&)url
           transition:(ui::PageTransition)transition;

// Returns YES if and only if |url| specifies a page for which we will prompt
// the user to authorize the use of geolocation for Omnibox queries.
- (BOOL)URLIsAuthorizationPromptingURL:(const GURL&)url;

// Starts updating device location if needed.
- (void)startUpdatingLocation;
// Stops updating device location.
- (void)stopUpdatingLocation;
// If the current location is not stale, then adds the current location to the
// current session entry for |tab| and reloads |tab|. If the current location
// is stale, then does nothing.
- (void)addLocationAndReloadTab:(Tab*)tab;
// Returns YES if and only if we should show an alert that prompts the user to
// authorize using geolocation for Omnibox queries.
- (BOOL)shouldShowAuthorizationAlert;
// Shows an alert that prompts the user to authorize using geolocation for
// Omnibox queries. Sets |weakTabToReload_| from |tab|, so that we can reload
// |tab| if the user authorizes using geolocation.
- (void)showAuthorizationAlertForTab:(Tab*)tab;
// Records |headerState| for the |kGeolocationHeaderSentOrNotHistogram|
// histogram.
- (void)recordHeaderState:(HeaderState)headerState;
// Records |authorizationAction|.
- (void)recordAuthorizationAction:(AuthorizationAction)authorizationAction;

@end

@implementation OmniboxGeolocationController

+ (OmniboxGeolocationController*)sharedInstance {
  static OmniboxGeolocationController* instance =
      [[OmniboxGeolocationController alloc] init];
  return instance;
}

- (void)triggerSystemPromptForNewUser:(BOOL)newUser {
  if (self.locationManager.locationServicesEnabled &&
      self.locationManager.authorizationStatus ==
          kCLAuthorizationStatusNotDetermined) {
    // Set |systemPrompt_|, so that
    // locationManagerDidChangeAuthorizationStatus: will know to handle any
    // CLAuthorizationStatus changes.
    //
    // TODO(crbug.com/661996): Remove the now useless
    // kAuthorizationStateNotDeterminedSystemPrompt from
    // omnibox_geolocation_local_state.h.
    systemPrompt_ = YES;
    self.localState.authorizationState =
        geolocation::kAuthorizationStateNotDeterminedSystemPrompt;

    // Turn on location updates, so that iOS will prompt the user.
    [self startUpdatingLocation];

    weakTabToReload_.reset();
    newUser_ = newUser;
  }
}

- (void)locationBarDidBecomeFirstResponder:
    (ios::ChromeBrowserState*)browserState {
  if (self.enabled && browserState && !browserState->IsOffTheRecord()) {
    [self startUpdatingLocation];
  }
}

- (void)locationBarDidResignFirstResponder:
    (ios::ChromeBrowserState*)browserState {
  // It's always okay to stop updating location.
  [self stopUpdatingLocation];
}

- (void)locationBarDidSubmitURL:(const GURL&)url
                     transition:(ui::PageTransition)transition
                   browserState:(ios::ChromeBrowserState*)browserState {
  // Stop updating the location when the user submits a query from the Omnibox.
  // We're not interested in further updates until the next time the user puts
  // the focus on the Omnbox.
  [self stopUpdatingLocation];
}

- (BOOL)addLocationToNavigationItem:(web::NavigationItem*)item
                       browserState:(ios::ChromeBrowserState*)browserState {
  // If this is incognito mode or is not an Omnibox query, then do nothing.
  //
  // Check the URL with URLIsQueryURL:transition: here and not
  // URLIsEligibleQueryURL:transition:, because we want to log the cases where
  // we did not send the X-Geo header due to the Google search domain not being
  // whitelisted.
  DCHECK(item);
  const GURL& url = item->GetURL();
  if (!browserState || browserState->IsOffTheRecord() ||
      ![self URLIsQueryURL:url transition:item->GetTransitionType()]) {
    return NO;
  }

  if (![[OmniboxGeolocationConfig sharedInstance] URLHasEligibleDomain:url]) {
    [self recordHeaderState:kHeaderStateNotSentDomainNotWhitelisted];
    return NO;
  }

  // At this point, we should only have Omnibox query URLs that are eligible
  // for geolocation.
  DCHECK([self URLIsEligibleQueryURL:url transition:item->GetTransitionType()]);

  HeaderState headerState;
  if (!self.locationManager.locationServicesEnabled) {
    headerState = kHeaderStateNotSentAuthorizationChromeDenied;
  } else {
    switch (self.localState.authorizationState) {
      case geolocation::kAuthorizationStateNotDeterminedWaiting:
      case geolocation::kAuthorizationStateNotDeterminedSystemPrompt:
        if (self.locationManager.authorizationStatus ==
                kCLAuthorizationStatusNotDetermined ||
            [self shouldShowAuthorizationAlert]) {
          headerState = kHeaderStateNotSentAuthorizationNotDetermined;
        } else {
          DCHECK(self.locationManager.authorizationStatus ==
                     kCLAuthorizationStatusAuthorizedAlways ||
                 self.locationManager.authorizationStatus ==
                     kCLAuthorizationStatusAuthorizedWhenInUse);
          headerState = kHeaderStateNotSentAuthorizationOmniboxDenied;
        }
        break;

      case geolocation::kAuthorizationStateDenied:
        switch (self.locationManager.authorizationStatus) {
          case kCLAuthorizationStatusNotDetermined:
            NOTREACHED();
            // To keep the compiler quiet about headerState not being
            // initialized in this switch case.
            headerState = kHeaderStateNotSentAuthorizationChromeDenied;
            break;
          case kCLAuthorizationStatusRestricted:
          case kCLAuthorizationStatusDenied:
            headerState = kHeaderStateNotSentAuthorizationChromeDenied;
            break;
          case kCLAuthorizationStatusAuthorizedAlways:
          case kCLAuthorizationStatusAuthorizedWhenInUse:
            headerState = kHeaderStateNotSentAuthorizationOmniboxDenied;
            break;
        }
        break;

      case geolocation::kAuthorizationStateAuthorized: {
        DCHECK(self.enabled);
        CLLocation* currentLocation = [self.locationManager currentLocation];
        if (!currentLocation) {
          headerState = kHeaderStateNotSentLocationNotAvailable;
        } else if (![currentLocation cr_isFreshEnough]) {
          headerState = kHeaderStateNotSentLocationStale;
        } else {
          NSDictionary* locationHTTPHeaders =
              @{ @"X-Geo" : [currentLocation cr_xGeoString] };
          item->AddHttpRequestHeaders(locationHTTPHeaders);
          headerState = kHeaderStateSent;

          NSTimeInterval acquisitionInterval =
              currentLocation.cr_acquisitionInterval;
          base::TimeDelta acquisitionTime = base::TimeDelta::FromMilliseconds(
              acquisitionInterval * base::Time::kMillisecondsPerSecond);
          UMA_HISTOGRAM_TIMES(kOmniboxQueryGeolocationAcquisitionTimeHistogram,
                              acquisitionTime);

          double horizontalAccuracy = currentLocation.horizontalAccuracy;
          UMA_HISTOGRAM_COUNTS_10000(
              kOmniboxQueryGeolocationHorizontalAccuracyHistogram,
              horizontalAccuracy);
        }
        break;
      }
    }
  }

  [self recordHeaderState:headerState];
  return headerState == kHeaderStateSent;
}

- (void)finishPageLoadForTab:(Tab*)tab loadSuccess:(BOOL)loadSuccess {
  if (tab.isPrerenderTab || !loadSuccess || !tab.browserState ||
      tab.browserState->IsOffTheRecord()) {
    return;
  }

  DCHECK(tab.webState->GetNavigationManager());
  web::NavigationItem* item =
      tab.webState->GetNavigationManager()->GetVisibleItem();
  if (![self URLIsAuthorizationPromptingURL:item->GetURL()] ||
      !self.locationManager.locationServicesEnabled) {
    return;
  }

  switch (self.locationManager.authorizationStatus) {
    case kCLAuthorizationStatusNotDetermined:
      // Prompt the user with the iOS system location authorization alert.
      //
      // Set |systemPrompt_|, so that
      // locationManagerDidChangeAuthorizationStatus: will know that any
      // CLAuthorizationStatus changes are coming from this specific prompt.
      systemPrompt_ = YES;
      self.localState.authorizationState =
          geolocation::kAuthorizationStateNotDeterminedSystemPrompt;
      [self startUpdatingLocation];

      // Save this tab in case we're able to transition to
      // kAuthorizationStateAuthorized.
      weakTabToReload_.reset(tab);
      break;

    case kCLAuthorizationStatusRestricted:
    case kCLAuthorizationStatusDenied:
      break;

    case kCLAuthorizationStatusAuthorizedAlways:
    case kCLAuthorizationStatusAuthorizedWhenInUse:
      // We might be in state kAuthorizationStateNotDeterminedSystemPrompt here
      // if we presented the iOS system location alert when
      // [CLLocationManager authorizationStatus] was
      // kCLAuthorizationStatusNotDetermined but the user managed to authorize
      // the app through some other flow; this might happen if the user
      // backgrounded the app or the app crashed. If so, then reset the state.
      if (self.localState.authorizationState ==
          geolocation::kAuthorizationStateNotDeterminedSystemPrompt) {
        self.localState.authorizationState =
            geolocation::kAuthorizationStateNotDeterminedWaiting;
      }
      // If the user has authorized the app to use location but not yet
      // explicitly authorized or denied using geolocation for Omnibox queries,
      // then present an alert.
      if (self.localState.authorizationState ==
              geolocation::kAuthorizationStateNotDeterminedWaiting &&
          [self shouldShowAuthorizationAlert]) {
        [self showAuthorizationAlertForTab:tab];
      }
      break;
  }
}

#pragma mark - Private

- (BOOL)enabled {
  return self.locationManager.locationServicesEnabled &&
         self.localState.authorizationState ==
             geolocation::kAuthorizationStateAuthorized;
}

- (OmniboxGeolocationLocalState*)localState {
  if (!localState_) {
    localState_.reset([[OmniboxGeolocationLocalState alloc]
        initWithLocationManager:self.locationManager]);
  }
  return localState_;
}

- (LocationManager*)locationManager {
  if (!locationManager_) {
    locationManager_.reset([[LocationManager alloc] init]);
    [locationManager_ setDelegate:self];
  }
  return locationManager_;
}

- (BOOL)URLIsEligibleQueryURL:(const GURL&)url
                   transition:(ui::PageTransition)transition {
  return [self URLIsQueryURL:url transition:transition] &&
         [[OmniboxGeolocationConfig sharedInstance] URLHasEligibleDomain:url];
}

- (BOOL)URLIsQueryURL:(const GURL&)url
           transition:(ui::PageTransition)transition {
  if (google_util::IsGoogleSearchUrl(url) &&
      (transition & ui::PAGE_TRANSITION_FROM_ADDRESS_BAR) != 0) {
    ui::PageTransition coreTransition = static_cast<ui::PageTransition>(
        transition & ui::PAGE_TRANSITION_CORE_MASK);
    if (PageTransitionCoreTypeIs(coreTransition,
                                 ui::PAGE_TRANSITION_GENERATED) ||
        PageTransitionCoreTypeIs(coreTransition, ui::PAGE_TRANSITION_RELOAD)) {
      return YES;
    }
  }
  return NO;
}

- (BOOL)URLIsAuthorizationPromptingURL:(const GURL&)url {
  // Per PRD: "Show a modal dialog upon reaching google.com or a search results
  // page..." However, we only want to do this for domains where we will send
  // location.
  return (google_util::IsGoogleHomePageUrl(url) ||
          google_util::IsGoogleSearchUrl(url)) &&
         [[OmniboxGeolocationConfig sharedInstance] URLHasEligibleDomain:url];
}

- (void)startUpdatingLocation {
  // Note that GeolocationUpdater will stop itself automatically after 5
  // seconds.
  [self.locationManager startUpdatingLocation];
}

- (void)stopUpdatingLocation {
  // Note that we don't need to initialize |locationManager_| here. If it's
  // nil, then it's not running.
  [locationManager_ stopUpdatingLocation];
}

- (void)addLocationAndReloadTab:(Tab*)tab {
  if (self.enabled && tab.webState) {
    // Make sure that GeolocationUpdater is running the first time we request
    // the current location.
    //
    // If GeolocationUpdater is not running, then it returns nil for the
    // current location. That's normally okay, because we cache the most recent
    // location in LocationManager. However, we arrive here when the user first
    // authorizes us to use location, so we may not have ever started
    // GeolocationUpdater.
    [self startUpdatingLocation];

    web::NavigationManager* navigationManager =
        tab.webState->GetNavigationManager();
    web::NavigationItem* item = navigationManager->GetVisibleItem();
    if ([self addLocationToNavigationItem:item browserState:tab.browserState]) {
      navigationManager->Reload(web::ReloadType::NORMAL,
                                false /* check_for_repost */);
    }
  }
}

- (BOOL)shouldShowAuthorizationAlert {
  base::Version previousVersion(self.localState.lastAuthorizationAlertVersion);
  if (!previousVersion.IsValid())
    return YES;

  base::Version currentVersion(version_info::GetVersionNumber());
  DCHECK(currentVersion.IsValid());
  return currentVersion.components()[0] != previousVersion.components()[0];
}

- (void)showAuthorizationAlertForTab:(Tab*)tab {
  // Save this tab in case we're able to transition to
  // kAuthorizationStateAuthorized.
  weakTabToReload_.reset(tab);

  authorizationAlert_.reset(
      [[OmniboxGeolocationAuthorizationAlert alloc] initWithDelegate:self]);
  [authorizationAlert_ showAuthorizationAlert];

  self.localState.lastAuthorizationAlertVersion =
      version_info::GetVersionNumber();
}

- (void)recordHeaderState:(HeaderState)headerState {
  UMA_HISTOGRAM_ENUMERATION(kGeolocationHeaderSentOrNotHistogram, headerState,
                            kHeaderStateCount);
}

- (void)recordAuthorizationAction:(AuthorizationAction)authorizationAction {
  if (newUser_) {
    newUser_ = NO;

    UMA_HISTOGRAM_ENUMERATION(kGeolocationAuthorizationActionNewUser,
                              authorizationAction, kAuthorizationActionCount);
  } else {
    UMA_HISTOGRAM_ENUMERATION(kGeolocationAuthorizationActionExistingUser,
                              authorizationAction, kAuthorizationActionCount);
  }
}

#pragma mark - LocationManagerDelegate

- (void)locationManagerDidChangeAuthorizationStatus:
    (LocationManager*)locationManager {
  if (systemPrompt_) {
    switch (self.locationManager.authorizationStatus) {
      case kCLAuthorizationStatusNotDetermined:
        // We may get a spurious notification about a transition to
        // |kCLAuthorizationStatusNotDetermined| when we first start location
        // services. Ignore it and don't reset |systemPrompt_| until we get a
        // real change.
        break;

      case kCLAuthorizationStatusRestricted:
      case kCLAuthorizationStatusDenied:
        self.localState.authorizationState =
            geolocation::kAuthorizationStateDenied;
        systemPrompt_ = NO;

        [self recordAuthorizationAction:kAuthorizationActionPermanentlyDenied];
        break;

      case kCLAuthorizationStatusAuthorizedAlways:
      case kCLAuthorizationStatusAuthorizedWhenInUse:
        self.localState.authorizationState =
            geolocation::kAuthorizationStateAuthorized;
        systemPrompt_ = NO;

        base::scoped_nsobject<Tab> tab([weakTabToReload_ retain]);
        [self addLocationAndReloadTab:tab];
        weakTabToReload_.reset();

        [self recordAuthorizationAction:kAuthorizationActionAuthorized];
        break;
    }
  }
}

#pragma mark - OmniboxGeolocationAuthorizationAlertDelegate

- (void)authorizationAlertDidAuthorize:
    (OmniboxGeolocationAuthorizationAlert*)authorizationAlert {
  self.localState.authorizationState =
      geolocation::kAuthorizationStateAuthorized;

  base::scoped_nsobject<Tab> tab([weakTabToReload_ retain]);
  [self addLocationAndReloadTab:tab];

  // Just resetting |authorizationAlert_| leads to a user-after-free crash
  // presumably due to a UIKit bug. Making authorizationAlert_ autorelease
  // will keep it alive long enough to avoid the crash. See crbug.com/381235
  authorizationAlert_.autorelease();
  weakTabToReload_.reset();

  [self recordAuthorizationAction:kAuthorizationActionAuthorized];
}

- (void)authorizationAlertDidCancel:
    (OmniboxGeolocationAuthorizationAlert*)authorizationAlert {
  // Leave authorization state as undetermined (not kAuthorizationStateDenied).
  // We won't use location, but we'll still be able to prompt at the next
  // application update.

  // Just resetting |authorizationAlert_| leads to a user-after-free crash
  // presumably due to a UIKit bug. Making authorizationAlert_ autorelease
  // will keep it alive long enough to avoid the crash. See crbug.com/381235
  authorizationAlert_.autorelease();
  weakTabToReload_.reset();

  [self recordAuthorizationAction:kAuthorizationActionDenied];
}

#pragma mark - OmniboxGeolocationController+Testing

- (void)setLocalState:(OmniboxGeolocationLocalState*)localState {
  localState_.reset([localState retain]);
}

- (void)setLocationManager:(LocationManager*)locationManager {
  locationManager_.reset([locationManager retain]);
}

@end
