// Copyright 2014 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/today_extension/today_view_controller.h"

#import <CommonCrypto/CommonDigest.h>
#import <NotificationCenter/NotificationCenter.h>
#include <unistd.h>

#include "base/at_exit.h"
#import "base/command_line.h"
#include "base/i18n/icu_util.h"
#include "base/ios/block_types.h"
#include "base/ios/ios_util.h"
#import "base/ios/weak_nsobject.h"
#include "base/mac/bundle_locations.h"
#include "base/mac/foundation_util.h"
#import "base/mac/scoped_block.h"
#import "base/mac/scoped_nsobject.h"
#include "base/metrics/histogram_macros.h"
#import "base/metrics/user_metrics_action.h"
#import "base/path_service.h"
#include "base/strings/sys_string_conversions.h"
#include "base/sys_info.h"
#include "components/open_from_clipboard/clipboard_recent_content_ios.h"
#include "ios/chrome/common/app_group/app_group_constants.h"
#import "ios/chrome/common/physical_web/physical_web_device.h"
#import "ios/chrome/common/physical_web/physical_web_scanner.h"
#include "ios/chrome/common/x_callback_url.h"
#import "ios/chrome/today_extension/footer_label.h"
#import "ios/chrome/today_extension/lock_screen_state.h"
#import "ios/chrome/today_extension/notification_center_button.h"
#import "ios/chrome/today_extension/physical_web_optin_footer.h"
#import "ios/chrome/today_extension/today_metrics_logger.h"
#include "ios/chrome/today_extension/ui_util.h"
#import "ios/chrome/today_extension/url_table_cell.h"
#include "ios/today_extension/grit/ios_today_extension_strings.h"
#import "net/base/mac/url_conversions.h"
#include "ui/base/l10n/l10n_util.h"
#include "ui/base/resource/resource_bundle.h"
#include "url/gurl.h"

namespace {

// The different state Physical Web can have at startup.
// Order is so that first 16 states code the four boolean tuple
// (optin, enable, bluetooth, lockscreen) and if user never opted in, states
// 16-19 code the lock and bluetooth state.
enum PhysicalWebInitialState {
  OPTOUT_DISABLE_BTOFF_UNLOCK,
  OPTOUT_DISABLE_BTOFF_LOCK,
  OPTOUT_DISABLE_BTON_UNLOCK,
  OPTOUT_DISABLE_BTON_LOCK,
  OPTOUT_ENABLE_BTOFF_UNLOCK,
  OPTOUT_ENABLE_BTOFF_LOCK,
  OPTOUT_ENABLE_BTON_UNLOCK,
  OPTOUT_ENABLE_BTON_LOCK,
  OPTIN_DISABLE_BTOFF_UNLOCK,
  OPTIN_DISABLE_BTOFF_LOCK,
  OPTIN_DISABLE_BTON_UNLOCK,
  OPTIN_DISABLE_BTON_LOCK,
  OPTIN_ENABLE_BTOFF_UNLOCK,
  OPTIN_ENABLE_BTOFF_LOCK,
  OPTIN_ENABLE_BTON_UNLOCK,
  OPTIN_ENABLE_BTON_LOCK,
  NEVEROPTED_BTOFF_UNLOCK,
  NEVEROPTED_BTOFF_LOCK,
  NEVEROPTED_BTON_UNLOCK,
  NEVEROPTED_BTON_LOCK,
  PHYSICAL_WEB_INITIAL_STATE_COUNT,

  // Helper flag values
  LOCKED_FLAG = 1 << 0,
  BLUETOOTH_FLAG = 1 << 1,
  PHYSICAL_WEB_ACTIVE_FLAG = 1 << 2,
  PHYSICAL_WEB_OPTED_IN_FLAG = 1 << 3,
  PHYSICAL_WEB_OPTED_IN_UNDECIDED_FLAG = 1 << 4,
};

enum PhysicalWebState {
  PHYSICAL_WEB_DISABLE,
  PHYSICAL_WEB_INITIAL_SCANNING,
  PHYSICAL_WEB_SCANNING,
  PHYSICAL_WEB_FROZEN,
  PHYSICAL_WEB_STATE_COUNT
};

// Global exit manager for LazyInstance and message loops. It is needed to
// enable the metrics logs.
base::AtExitManager* g_at_exit_ = nullptr;

const CGFloat kPhysicalWebInitialScanningDelay = 2;
const CGFloat kPhysicalWebRefreshDelay = 2;
const CGFloat kPhysicalWebScanningDelay = 5;

const int kMaxNumberOfPhysicalWebItem = 2;

// Setting to track if user ever interacted with physical web.
NSString* const kPhysicalWebInitialStateDonePreference =
    @"PhysicalInitialStateDone";

// Setting to track if physical web has been turned off by the user.
NSString* const kPhysicalWebDisabledPreference = @"PhysicalWebDisabled";

// Setting to track if user opted in for physical web.
NSString* const kPhysicalWebOptedInPreference = @"PhysicalWebOptedIn";

}  // namespace

@interface TodayViewController ()<LockScreenStateDelegate,
                                  NCWidgetProviding,
                                  PhysicalWebScannerDelegate,
                                  UITableViewDataSource>

// Loads the current locale .pak file for localization.
- (void)loadLocalization;

// Whether all the physical web devices are displayed (YES) or only
// |kMaxNumberOfPhysicalWebItem| (NO).
@property(nonatomic, assign) BOOL displayAllPhysicalWebItems;

// Returns the string contained in the OS pasteboard if it contains a valid URL.
// Returns nil otherwise.
- (NSString*)pasteURLString;

// Updates the URL displayed in the "Open Copied Link" button.
- (void)updatePasteURLButton;

// Sets the footer label that is displayed in the widget.
- (void)setFooterLabel:(FooterLabel)footerLabel forceUpdate:(BOOL)force;

// Computes the height needed by the whole notification center widget with the
// context (orientation, number of beacons...).
- (CGFloat)widgetHeight;

// Change the widget height to |height| if |self isWidgetExpandable| is true;
- (void)setHeight:(CGFloat)height;

// Returns whether the height of the widget can be changed.
- (BOOL)isWidgetExpandable;

// Computes the height needed by the |_urlsTable| table view.
- (CGFloat)urlsTableHeight;

// Refreshes the data and redraws the widget.
- (void)refreshWidget;

// Sets settings wether physical web is enabled.
- (void)setPhysicalWebEnabled:(BOOL)enabled;

// Starts the physical web scanner.
- (void)startPhysicalWeb;

// Stops the physical web scanner. Hide the beacons in the table.
- (void)stopPhysicalWeb;

// Handler for the "New Tab" button. Sends a new tab order to Chrome.
- (void)newTab:(id)sender;

// Handler for the "Voice Search" button. Sends a voice search order to Chrome.
- (void)voiceSearch:(id)sender;

// Called when "Open Copied Link" is tapped. Sends an open url order to Chrome
// to open |url|.
- (void)openClipboardURLInChrome:(NSString*)url;

// Called when a physical web button is tapped. Sends an open url order to
// Chrome to open |url|.
- (void)openPhysicalWebURLInChrome:(NSString*)url;

// Sends an order to Chrome to open |url|.
- (void)openURLInChrome:(NSString*)url;

// Opens Chrome with an x-callback-url with command "app-group-command". The
// |command| and |parameter| are passed via a shared sandbox NSDictionary.
- (void)sendToChromeCommand:(NSString*)command
              withParameter:(NSString*)parameter;

// Creates (or reuses) an autoreleased URLTableCell to contain the pasteboard
// URL.
- (URLTableCell*)cellForPasteboardURL;

// Creates (or reuses) an autoreleased URLTableCell to contain the "Show more
// beacons" button.
- (URLTableCell*)cellForShowMore;

// Creates (or reuses) an autoreleased URLTableCell to contain the physical web
// URL. |index| is the index of the PhysicalWebDevice in |_scanner devices|
// table.
- (URLTableCell*)cellForPhysicalWebURLAtIndex:(NSInteger)index;

// Sends an histogram coding the initial state of the four variables:
// - bluetooth on/off
// - lock screen locked/unlocked
// - physical web enabled/disabled
// - physical web opted in/opted out/not yet decided.
- (void)reportInitialState;

@end

@implementation TodayViewController {
  base::scoped_nsobject<NotificationCenterButton> _newTabButton;
  base::scoped_nsobject<NotificationCenterButton> _voiceSearchButton;
  base::scoped_nsobject<UIView> _containerView;
  base::scoped_nsobject<UILabel> _emptyWidgetLabel;
  base::scoped_nsobject<UIStackView> _buttonsView;
  base::scoped_nsobject<UIStackView> _contentStackView;
  base::scoped_nsobject<NSLayoutConstraint> _tableViewHeight;

  base::scoped_nsobject<UITableView> _urlsTable;
  base::scoped_nsobject<PhysicalWebScanner> _scanner;
  base::scoped_nsobject<NSString> _pasteURL;
  base::scoped_nsprotocol<id<FooterLabel>> _footerLabel;

  CGFloat _defaultLeadingMarginInset;

  NSInteger _maxNumberOfURLs;
  BOOL _displayAllPhysicalWebItems;
  BOOL _physicalWebDetected;

  // Whether the histogram giving the initial state was sent.
  BOOL _initialStateReported;

  // Whether physical web is active (the user enabled it). The scanning for
  // devices can be started.
  BOOL _physicalWebActive;

  // Whether the |_scanner| actually started scanning for devices.
  BOOL _physicalWebRunning;

  // Whether the user has ever seen a beacon and interacted with physical web.
  // If not, don't show any UI if there is no beacon around.
  BOOL _physicalWebInInitialState;

  // Whether the user opted in. Queries to resolve the URLs title can be issued.
  BOOL _physicalWebOptedIn;

  // Whether bluetooth is on. Default to NO, until notification that the
  // bluetooth is on is received.
  BOOL _bluetoothIsOn;

  PhysicalWebState _physicalWebState;
  FooterLabel _currentFooterLabel;

  // A boolean to track if the widget is currently on screen or not.
  BOOL _hidden;

  // Whether a refresh of the widget is scheduled.
  BOOL _refreshScheduled;

  // Whether the widget is displayed in notification center (NO) or as a
  // shortcut widget (YES).
  BOOL _displayedInShortcutMode;

  // The Recent clipboard service that handles the clipboard timeout.
  std::unique_ptr<ClipboardRecentContentIOS> _clipboardRecentContent;
}

@synthesize displayAllPhysicalWebItems = _displayAllPhysicalWebItems;

- (NSString*)pasteURLString {
  GURL pasteURL;
  _clipboardRecentContent->GetRecentURLFromClipboard(&pasteURL);

  if (pasteURL.is_valid() && pasteURL.SchemeIsHTTPOrHTTPS()) {
    return base::SysUTF8ToNSString(pasteURL.spec());
  }
  return nil;
}

- (void)loadView {
  static dispatch_once_t initialization_token;
  dispatch_once(&initialization_token, ^{
    if (!g_at_exit_)
      g_at_exit_ = new base::AtExitManager;
    base::CommandLine::Init(0, nullptr);
    base::FilePath path = base::FilePath(
        base::SysNSStringToUTF8([[NSBundle mainBundle] resourcePath]));
    path = path.DirName().DirName().AppendASCII("icudtl.dat");
    DCHECK(access(path.value().c_str(), F_OK) != -1);
    base::ios::OverridePathOfEmbeddedICU(path.value().c_str());
    base::i18n::InitializeICU();
    [self loadLocalization];
  });

  _defaultLeadingMarginInset = ui_util::kDefaultLeadingMarginInset;

  if (base::ios::IsRunningOnIOS10OrLater()) {
    [[self extensionContext]
        setWidgetLargestAvailableDisplayMode:NCWidgetDisplayModeExpanded];
  }
  _clipboardRecentContent.reset(new ClipboardRecentContentIOS(
      std::string(), app_group::GetGroupUserDefaults()));
  TodayMetricsLogger::GetInstance()->RecordUserAction(
      base::UserMetricsAction("TodayExtension.ExtensionInitialized"));

  _physicalWebInInitialState = ![[NSUserDefaults standardUserDefaults]
      boolForKey:kPhysicalWebInitialStateDonePreference];

  _physicalWebActive = ![[NSUserDefaults standardUserDefaults]
      boolForKey:kPhysicalWebDisabledPreference];
  _physicalWebOptedIn = [[NSUserDefaults standardUserDefaults]
      boolForKey:kPhysicalWebOptedInPreference];

  _containerView.reset([[UIView alloc] initWithFrame:CGRectZero]);
  [_containerView setTranslatesAutoresizingMaskIntoConstraints:NO];
  self.view = _containerView.get();

  // Sets a transparent image as layer to prevent iOS from optimizing out the
  // touch events on the transparent part of the widget.
  UIGraphicsBeginImageContextWithOptions(CGSizeMake(1, 1), NO, 0);
  UIImage* img = UIGraphicsGetImageFromCurrentImageContext();
  UIGraphicsEndImageContext();
  self.view.layer.contents = (id)[img CGImage];

  _maxNumberOfURLs = NSIntegerMax;
  [self updatePasteURLButton];
  [self setHeight:[self widgetHeight]];

  _newTabButton.reset([[NotificationCenterButton alloc]
        initWithTitle:l10n_util::GetNSString(
                          IDS_IOS_NEW_TAB_TITLE_TODAY_EXTENSION)
                 icon:@"todayview_new_tab"
               target:self
               action:@selector(newTab:)
      backgroundColor:ui_util::BackgroundColor()
             inkColor:ui_util::InkColor()
           titleColor:[UIColor blackColor]]);
  [_newTabButton setButtonSpacesSeparator:ui_util::kUIButtonSeparator
                               frontShift:ui_util::kUIButtonFrontShift
                        horizontalPadding:0
                          verticalPadding:0];
  [_newTabButton setCornerRadius:ui_util::kUIButtonCornerRadius];

  _voiceSearchButton.reset([[NotificationCenterButton alloc]
        initWithTitle:l10n_util::GetNSString(
                          IDS_IOS_VOICE_SEARCH_TODAY_EXTENSION_TITLE)
                 icon:@"todayview_voice_search"
               target:self
               action:@selector(voiceSearch:)
      backgroundColor:ui_util::BackgroundColor()
             inkColor:ui_util::InkColor()
           titleColor:[UIColor blackColor]]);
  [_voiceSearchButton setButtonSpacesSeparator:ui_util::kUIButtonSeparator
                                    frontShift:ui_util::kUIButtonFrontShift
                             horizontalPadding:0
                               verticalPadding:0];
  [_voiceSearchButton setCornerRadius:ui_util::kUIButtonCornerRadius];

  _buttonsView.reset([[UIStackView alloc]
      initWithArrangedSubviews:@[ _newTabButton, _voiceSearchButton ]]);

  [_buttonsView setAxis:UILayoutConstraintAxisHorizontal];
  [_buttonsView setDistribution:UIStackViewDistributionFillEqually];
  [_buttonsView setSpacing:ui_util::kFirstLineButtonMargin];
  [_buttonsView setLayoutMarginsRelativeArrangement:YES];
  [_buttonsView setTranslatesAutoresizingMaskIntoConstraints:NO];

  [[_buttonsView heightAnchor]
      constraintEqualToConstant:ui_util::kFirstLineHeight]
      .active = YES;

  CGFloat chromeIconXOffset =
      _defaultLeadingMarginInset + ui_util::ChromeIconOffset();
  CGFloat firstLineOuterMargin =
      chromeIconXOffset - ui_util::kFirstLineButtonMargin;
  [_buttonsView
      setLayoutMargins:UIEdgeInsetsMake(ui_util::kFirstLineButtonMargin,
                                        firstLineOuterMargin,
                                        ui_util::kFirstLineButtonMargin,
                                        firstLineOuterMargin)];

  _urlsTable.reset([[UITableView alloc] initWithFrame:CGRectZero]);
  [_urlsTable setDataSource:self];
  [_urlsTable setRowHeight:ui_util::kSecondLineHeight];
  [_urlsTable setSeparatorStyle:UITableViewCellSeparatorStyleNone];
  _tableViewHeight.reset(
      [[_urlsTable heightAnchor] constraintEqualToConstant:0]);
  [_tableViewHeight setActive:YES];

  _contentStackView.reset([[UIStackView alloc]
      initWithArrangedSubviews:@[ _buttonsView, _urlsTable ]]);
  [[_urlsTable widthAnchor]
      constraintEqualToAnchor:[_contentStackView widthAnchor]]
      .active = YES;
  [_contentStackView setAxis:UILayoutConstraintAxisVertical];
  [_contentStackView setDistribution:UIStackViewDistributionFill];
  [_contentStackView setSpacing:0];
  [_contentStackView setLayoutMarginsRelativeArrangement:NO];
  [_contentStackView setTranslatesAutoresizingMaskIntoConstraints:NO];
  [_containerView addSubview:_contentStackView];
  [[_contentStackView topAnchor]
      constraintEqualToAnchor:[_containerView topAnchor]]
      .active = YES;
  [[_contentStackView widthAnchor]
      constraintEqualToAnchor:[_containerView widthAnchor]]
      .active = YES;
  [[_contentStackView centerXAnchor]
      constraintEqualToAnchor:[_containerView centerXAnchor]]
      .active = YES;

  if (base::ios::IsRunningOnIOS10OrLater()) {
    _emptyWidgetLabel.reset([[UILabel alloc] initWithFrame:CGRectZero]);
    [_emptyWidgetLabel
        setText:l10n_util::GetNSString(IDS_IOS_EMPTY_TODAY_EXTENSION_TEXT)];
    [_emptyWidgetLabel setFont:[UIFont systemFontOfSize:16]];
    [_emptyWidgetLabel setTextColor:ui_util::emptyLabelColor()];
    [_emptyWidgetLabel setTranslatesAutoresizingMaskIntoConstraints:NO];
    [_containerView addSubview:_emptyWidgetLabel];
    [NSLayoutConstraint activateConstraints:@[
      [[_emptyWidgetLabel centerXAnchor]
          constraintEqualToAnchor:[_containerView centerXAnchor]],
      [[_emptyWidgetLabel centerYAnchor]
          constraintEqualToAnchor:[_containerView centerYAnchor]
                         constant:ui_util::kEmptyLabelYOffset]
    ]];
    [_emptyWidgetLabel setHidden:YES];
  }

  _hidden = NO;
  [self refreshWidget];
}

- (void)loadLocalization {
  NSArray* languageList = [[NSBundle mainBundle] preferredLocalizations];
  NSString* firstLocale = [languageList objectAtIndex:0];

  if (!firstLocale) {
    firstLocale = @"en";
  }
  base::FilePath resource_path([[base::mac::FrameworkBundle()
      pathForResource:@"locale"
               ofType:@"pak"
          inDirectory:@""
      forLocalization:firstLocale] fileSystemRepresentation]);
  ResourceBundle::InitSharedInstanceWithPakPath(resource_path);
}

- (void)updatePasteURLButton {
  NSString* pasteURLString = [self pasteURLString];
  if ([pasteURLString isEqualToString:_pasteURL])
    return;
  _pasteURL.reset([pasteURLString copy]);
  if (_pasteURL) {
    TodayMetricsLogger::GetInstance()->RecordUserAction(
        base::UserMetricsAction("TodayExtension.CopiedURLDisplayed"));
  }
  [self refreshWidget];
}

- (void)setHeight:(CGFloat)height {
  if (![self isWidgetExpandable]) {
    return;
  }

  CGSize size = CGSizeMake(0, height);
  if (base::ios::IsRunningOnIOS10OrLater()) {
    size = [self.extensionContext
        widgetMaximumSizeForDisplayMode:[self.extensionContext
                                                widgetActiveDisplayMode]];
    CGSize minSize = [self.extensionContext
        widgetMaximumSizeForDisplayMode:NCWidgetDisplayModeCompact];
    size.height = MIN(height, size.height);
    // Empirically, widget has to be bigger in Expanded mode than in Compact
    // mode.
    // If it is not the case, some resize instructions can be lost.
    // These tests have been done on iPhone 7 on iOS10.0 and 10.1.
    size.height = MAX(size.height, minSize.height + 1);
  }
  if (self.preferredContentSize.height == size.height) {
    // If the height is already that size, avoid trigger UI updates.
    return;
  }
  self.preferredContentSize = size;
}

- (BOOL)isWidgetExpandable {
  if (base::ios::IsRunningOnIOS10OrLater()) {
    return [self.extensionContext widgetActiveDisplayMode] ==
           NCWidgetDisplayModeExpanded;
  }
  return YES;
}

- (CGFloat)widgetHeight {
  if (_hidden) {
    return ui_util::kFirstLineHeight;
  }
  CGFloat height = 0;
  if (!_displayedInShortcutMode)
    height += ui_util::kFirstLineHeight;
  return height + [self urlsTableHeight] +
         [_footerLabel heightForWidth:[_containerView frame].size.width];
}

- (CGFloat)urlsTableHeight {
  return [self tableView:_urlsTable numberOfRowsInSection:0] *
         ui_util::kSecondLineHeight;
}

- (void)scheduleRefreshWidget {
  if (_refreshScheduled)
    return;

  _refreshScheduled = YES;
  [self performSelector:@selector(refreshWidget)
             withObject:nil
             afterDelay:kPhysicalWebRefreshDelay];
}

- (void)refreshWidget {
  [NSObject cancelPreviousPerformRequestsWithTarget:self
                                           selector:@selector(refreshWidget)
                                             object:nil];
  _refreshScheduled = NO;
  [_urlsTable reloadData];
  [_tableViewHeight setConstant:[self urlsTableHeight]];
  [self.view setNeedsLayout];
  CGFloat height = [self widgetHeight];
  BOOL empty = height == 0;
  [_emptyWidgetLabel setHidden:!empty];
  [self setHeight:height];
}

- (void)setFooterLabel:(FooterLabel)footerLabel forceUpdate:(BOOL)force {
  if (footerLabel == _currentFooterLabel && !force)
    return;
  if (footerLabel == PW_OPTIN_DIALOG &&
      _currentFooterLabel != PW_OPTIN_DIALOG) {
    TodayMetricsLogger::GetInstance()->RecordUserAction(
        base::UserMetricsAction("PhysicalWeb.OptinDisplayed"));
  }

  _currentFooterLabel = footerLabel;
  [[_footerLabel view] removeFromSuperview];
  base::WeakNSObject<TodayViewController> weakSelf(self);
  ProceduralBlock learnMoreBlock = ^{
    [weakSelf learnMore];
  };

  ProceduralBlock turnOffPhysicalWeb;
  ProceduralBlock turnOnPhysicalWeb;
  ProceduralBlock optInPhysicalWeb;
  ProceduralBlock optOutPhysicalWeb;

  if (![[LockScreenState sharedInstance] isScreenLocked]) {
    turnOffPhysicalWeb = ^{
      [weakSelf setPhysicalWebEnabled:NO];
    };

    turnOnPhysicalWeb = ^{
      [weakSelf setPhysicalWebEnabled:YES];
    };

    optInPhysicalWeb = ^{
      [weakSelf physicalWebOptIn];
    };

    optOutPhysicalWeb = ^{
      [weakSelf physicalWebOptOut];
    };
  }

  switch (footerLabel) {
    case NO_FOOTER_LABEL:
      _footerLabel.reset();
      break;
    case PW_IS_OFF_FOOTER_LABEL:
      _footerLabel.reset([[PWIsOffFooterLabel alloc]
          initWithLearnMoreBlock:learnMoreBlock
                     turnOnBlock:turnOnPhysicalWeb]);
      break;
    case PW_IS_ON_FOOTER_LABEL:
      _footerLabel.reset([[PWIsOnFooterLabel alloc]
          initWithLearnMoreBlock:learnMoreBlock
                    turnOffBlock:turnOffPhysicalWeb]);
      break;
    case PW_SCANNING_FOOTER_LABEL:
      _footerLabel.reset([[PWScanningFooterLabel alloc]
          initWithLearnMoreBlock:learnMoreBlock
                    turnOffBlock:turnOffPhysicalWeb]);
      break;
    case PW_OPTIN_DIALOG:
      _footerLabel.reset([[PhysicalWebOptInFooter alloc]
          initWithLeftInset:_defaultLeadingMarginInset
             learnMoreBlock:learnMoreBlock
                optinAction:optInPhysicalWeb
              dismissAction:optOutPhysicalWeb]);
      break;
    case PW_BT_OFF_FOOTER_LABEL:
      _footerLabel.reset(
          [[PWBTOffFooterLabel alloc] initWithLearnMoreBlock:learnMoreBlock]);
      break;
    case FOOTER_LABEL_COUNT:
      NOTREACHED();
      break;
  }
  if (_footerLabel) {
    [_contentStackView addArrangedSubview:[_footerLabel view]];
    [[[_footerLabel view] widthAnchor]
        constraintEqualToAnchor:[_contentStackView widthAnchor]]
        .active = YES;
    [[[_footerLabel view] centerXAnchor]
        constraintEqualToAnchor:[_contentStackView centerXAnchor]]
        .active = YES;
    [[[_footerLabel view] bottomAnchor]
        constraintEqualToAnchor:[self view].bottomAnchor]
        .active = YES;
  }
  [self refreshWidget];
}

- (void)learnMore {
  [self openURLInChrome:
            @"https://support.google.com/chrome/?p=chrome_physical_web"];
}

- (void)setPhysicalWebEnabled:(BOOL)enabled {
  if (enabled == _physicalWebActive)
    return;
  _physicalWebActive = enabled;
  [[NSUserDefaults standardUserDefaults]
      setBool:!enabled
       forKey:kPhysicalWebDisabledPreference];
  if (enabled) {
    [self startPhysicalWeb];
  } else {
    [self stopPhysicalWeb];
  }
}

- (void)lockScreenStateDidChange:(LockScreenState*)lockScreenState {
  [self updatePhysicalWebFooterForceUpdate:YES];
}

- (void)newTab:(id)sender {
  TodayMetricsLogger::GetInstance()->RecordUserAction(
      base::UserMetricsAction("TodayExtension.NewTabPressed"));

  NSString* command =
      base::SysUTF8ToNSString(app_group::kChromeAppGroupNewTabCommand);
  [self sendToChromeCommand:command withParameter:nil];
}

- (void)voiceSearch:(id)sender {
  TodayMetricsLogger::GetInstance()->RecordUserAction(
      base::UserMetricsAction("TodayExtension.VoiceSearchPressed"));
  NSString* command =
      base::SysUTF8ToNSString(app_group::kChromeAppGroupVoiceSearchCommand);
  [self sendToChromeCommand:command withParameter:nil];
}

- (void)openClipboardURLInChrome:(NSString*)url {
  TodayMetricsLogger::GetInstance()->RecordUserAction(
      base::UserMetricsAction("TodayExtension.OpenClipboardPressed"));
  [self openURLInChrome:url];
}

- (void)openPhysicalWebURLInChrome:(NSString*)url {
  TodayMetricsLogger::GetInstance()->RecordUserAction(
      base::UserMetricsAction("TodayExtension.PhysicalWebPressed"));
  TodayMetricsLogger::GetInstance()->RecordUserAction(
      base::UserMetricsAction("PhysicalWeb.UrlSelected"));
  [self openURLInChrome:url];
}

- (void)openURLInChrome:(NSString*)url {
  TodayMetricsLogger::GetInstance()->RecordUserAction(
      base::UserMetricsAction("TodayExtension.ActionTriggered"));
  GURL pasteURL(base::SysNSStringToUTF8(url));
  if (!pasteURL.is_valid()) {
    return;
  }
  NSString* command =
      base::SysUTF8ToNSString(app_group::kChromeAppGroupOpenURLCommand);
  [self sendToChromeCommand:command withParameter:url];
}

- (void)sendToChromeCommand:(NSString*)command
              withParameter:(NSString*)parameter {
  base::scoped_nsobject<NSUserDefaults> sharedDefaults(
      [[NSUserDefaults alloc] initWithSuiteName:app_group::ApplicationGroup()]);

  base::scoped_nsobject<NSMutableDictionary> commandDictionary(
      [[NSMutableDictionary alloc] init]);
  [commandDictionary
      setObject:[NSDate date]
         forKey:base::SysUTF8ToNSString(
                    app_group::kChromeAppGroupCommandTimePreference)];
  [commandDictionary
      setObject:@"TodayExtension"
         forKey:base::SysUTF8ToNSString(
                    app_group::kChromeAppGroupCommandAppPreference)];

  [commandDictionary
      setObject:command
         forKey:base::SysUTF8ToNSString(
                    app_group::kChromeAppGroupCommandCommandPreference)];

  if (parameter) {
    [commandDictionary
        setObject:parameter
           forKey:base::SysUTF8ToNSString(
                      app_group::kChromeAppGroupCommandParameterPreference)];
  }
  [sharedDefaults setObject:commandDictionary
                     forKey:base::SysUTF8ToNSString(
                                app_group::kChromeAppGroupCommandPreference)];
  [sharedDefaults synchronize];

  NSString* scheme = base::mac::ObjCCast<NSString>([[NSBundle mainBundle]
      objectForInfoDictionaryKey:@"KSChannelChromeScheme"]);
  if (!scheme)
    return;
  const GURL openURL =
      CreateXCallbackURL(base::SysNSStringToUTF8(scheme),
                         app_group::kChromeAppGroupXCallbackCommand);
  [self.extensionContext openURL:net::NSURLWithGURL(openURL)
               completionHandler:nil];
}

- (void)startPhysicalWeb {
  if (_physicalWebRunning)
    return;
  _physicalWebRunning = YES;

  // Reset scanner to reset previously detected devices.
  [_scanner stop];
  _scanner.reset([[PhysicalWebScanner alloc] initWithDelegate:self]);
  if (_physicalWebOptedIn) {
    [_scanner setNetworkRequestEnabled:YES];
  }
  _physicalWebState = PHYSICAL_WEB_INITIAL_SCANNING;
  _displayAllPhysicalWebItems = NO;
  [self updatePhysicalWebFooterForceUpdate:NO];
  [self refreshWidget];
  [_scanner start];
  // Refresh the UI after 2 seconds.
  [self performSelector:@selector(physicalWebEndOfInitialScanning)
             withObject:nil
             afterDelay:kPhysicalWebInitialScanningDelay];
}

- (void)physicalWebEndOfInitialScanning {
  _physicalWebState = PHYSICAL_WEB_SCANNING;
  if (_physicalWebDetected) {
    [self refreshWidget];
  }
  // After 5 seconds, stop scanning and refresh the UI.
  [self performSelector:@selector(physicalWebEndOfScanning)
             withObject:nil
             afterDelay:kPhysicalWebScanningDelay];
}

- (void)physicalWebEndOfScanning {
  [_scanner stop];
  _physicalWebState = PHYSICAL_WEB_FROZEN;
  if (_physicalWebOptedIn || !_physicalWebDetected) {
    [self updatePhysicalWebFooterForceUpdate:NO];
    [self refreshWidget];
  }
}

- (void)stopPhysicalWeb {
  _physicalWebRunning = NO;
  _physicalWebDetected = NO;
  _refreshScheduled = NO;
  [NSObject cancelPreviousPerformRequestsWithTarget:self];
  _physicalWebState = PHYSICAL_WEB_DISABLE;
  [_scanner stop];
  _scanner.reset();
  [self updatePhysicalWebFooterForceUpdate:NO];
  [self refreshWidget];
}

- (FooterLabel)footerForCurrentPhysicalWebState {
  if (_hidden) {
    return NO_FOOTER_LABEL;
  }

  if (!_bluetoothIsOn) {
    if (_physicalWebActive && _physicalWebOptedIn) {
      return PW_BT_OFF_FOOTER_LABEL;
    }
    return NO_FOOTER_LABEL;
  }

  // Bluetooth is on.
  if (!_physicalWebActive) {
    return PW_IS_OFF_FOOTER_LABEL;
  }

  if (!_physicalWebOptedIn) {
    // User did not opt in. Show opt-in screen if devices are detected.
    if (_physicalWebDetected) {
      return PW_OPTIN_DIALOG;
    } else {
      if (_physicalWebInInitialState) {
        return NO_FOOTER_LABEL;
      } else {
        return PW_IS_ON_FOOTER_LABEL;
      }
    }
  }

  if (_physicalWebState == PHYSICAL_WEB_FROZEN) {
    return PW_IS_ON_FOOTER_LABEL;
  } else {
    return PW_SCANNING_FOOTER_LABEL;
  }
  NOTREACHED();
}

- (void)updatePhysicalWebFooterForceUpdate:(BOOL)force {
  [self setFooterLabel:[self footerForCurrentPhysicalWebState]
           forceUpdate:force];
}

- (void)physicalWebOptOut {
  _physicalWebOptedIn = NO;
  _physicalWebInInitialState = NO;
  [self setPhysicalWebEnabled:NO];
  [[NSUserDefaults standardUserDefaults] setBool:NO
                                          forKey:kPhysicalWebOptedInPreference];
  [[NSUserDefaults standardUserDefaults]
      setBool:YES
       forKey:kPhysicalWebInitialStateDonePreference];
}

- (void)physicalWebOptIn {
  [[NSUserDefaults standardUserDefaults] setBool:YES
                                          forKey:kPhysicalWebOptedInPreference];
  [[NSUserDefaults standardUserDefaults]
      setBool:YES
       forKey:kPhysicalWebInitialStateDonePreference];
  _physicalWebInInitialState = NO;
  _physicalWebOptedIn = YES;
  [self stopPhysicalWeb];
  [self startPhysicalWeb];
}

- (void)viewWillAppear:(BOOL)animated {
  [super viewWillAppear:animated];
  _displayedInShortcutMode = NO;
  if (base::ios::IsRunningOnIOS10OrLater()) {
    CGSize maxHeightExpanded = [self.extensionContext
        widgetMaximumSizeForDisplayMode:NCWidgetDisplayModeExpanded];
    CGSize maxHeightCompact = [self.extensionContext
        widgetMaximumSizeForDisplayMode:NCWidgetDisplayModeCompact];
    _displayedInShortcutMode =
        maxHeightExpanded.height == maxHeightCompact.height;
    [_buttonsView setHidden:_displayedInShortcutMode];
  }
}

- (void)viewDidAppear:(BOOL)animated {
  [super viewDidAppear:animated];
  _hidden = NO;
  _initialStateReported = NO;
  [[LockScreenState sharedInstance] setDelegate:self];
  _pasteURL.reset();
  [self updatePasteURLButton];
  TodayMetricsLogger::GetInstance()->RecordUserAction(
      base::UserMetricsAction("TodayExtension.ExtensionDisplayed"));
  [_scanner stop];
  if (!_displayedInShortcutMode || !_physicalWebInInitialState) {
    _scanner.reset([[PhysicalWebScanner alloc] initWithDelegate:self]);
  }
  _physicalWebRunning = NO;
}

- (void)viewWillDisappear:(BOOL)animated {
  [super viewWillDisappear:animated];
  if (_physicalWebRunning) {
    UMA_HISTOGRAM_COUNTS_100("PhysicalWeb.TotalBeaconsDetected",
                             [[_scanner devices] count]);
  }
  TodayMetricsLogger::GetInstance()->RecordUserAction(
      base::UserMetricsAction("TodayExtension.ExtensionDismissed"));

  _hidden = YES;
  [[LockScreenState sharedInstance] setDelegate:nil];
  [self setFooterLabel:NO_FOOTER_LABEL forceUpdate:NO];
  [self stopPhysicalWeb];
  [self refreshWidget];
  if (base::ios::IsRunningOnIOS10OrLater()) {
    // Prepare for next display whch can be on Shortcut mode.
    [_buttonsView setHidden:YES];
  }
}

- (void)scannerUpdatedDevices:(PhysicalWebScanner*)scanner {
  _physicalWebDetected =
      [_scanner unresolvedBeaconsCount] + [[_scanner devices] count] > 0;
  if (!_physicalWebOptedIn && _physicalWebDetected) {
    [self updatePhysicalWebFooterForceUpdate:NO];
    return;
  }
  if (_physicalWebState == PHYSICAL_WEB_SCANNING) {
    [self scheduleRefreshWidget];
  }
}

- (void)reportInitialState {
  if (_initialStateReported)
    return;

  _initialStateReported = YES;
  int state =
      [[LockScreenState sharedInstance] isScreenLocked] ? LOCKED_FLAG : 0;
  state |= (_bluetoothIsOn ? BLUETOOTH_FLAG : 0);
  if (!_physicalWebInInitialState) {
    state |= (_physicalWebActive ? PHYSICAL_WEB_ACTIVE_FLAG : 0);
    state |= (_physicalWebOptedIn ? PHYSICAL_WEB_OPTED_IN_FLAG : 0);
  } else {
    state |= PHYSICAL_WEB_OPTED_IN_UNDECIDED_FLAG;
  }
  DCHECK(state < PHYSICAL_WEB_INITIAL_STATE_COUNT);
  UMA_HISTOGRAM_ENUMERATION("PhysicalWeb.InitialState", state,
                            PHYSICAL_WEB_INITIAL_STATE_COUNT);
}

- (void)scannerBluetoothStatusUpdated:(PhysicalWebScanner*)scanner {
  _bluetoothIsOn = [scanner bluetoothEnabled];
  [self reportInitialState];

  if (_bluetoothIsOn && _physicalWebActive) {
    [self startPhysicalWeb];
  } else {
    [self stopPhysicalWeb];
  }
  [self updatePhysicalWebFooterForceUpdate:NO];
}

- (NSInteger)tableView:(UITableView*)tableView
    numberOfRowsInSection:(NSInteger)section {
  DCHECK(tableView == _urlsTable.get());
  DCHECK(section == 0);
  if (_hidden)
    return 0;
  NSInteger rowCount = [[_scanner devices] count];
  if (!_displayAllPhysicalWebItems && rowCount > kMaxNumberOfPhysicalWebItem) {
    // Add one row for the "Show more" button.
    rowCount = kMaxNumberOfPhysicalWebItem + 1;
  }
  if (_physicalWebState == PHYSICAL_WEB_INITIAL_SCANNING) {
    rowCount = 0;
  }
  if (_pasteURL)
    rowCount++;
  if (rowCount > _maxNumberOfURLs)
    rowCount = _maxNumberOfURLs;
  return rowCount;
}

- (URLTableCell*)cellForPasteboardURL {
  NSString* pasteboardReusableID = @"PasteboardCell";
  URLTableCell* cell = base::mac::ObjCCast<URLTableCell>(
      [_urlsTable dequeueReusableCellWithIdentifier:pasteboardReusableID]);
  if (cell) {
    [cell setTitle:l10n_util::GetNSString(
                       IDS_IOS_OPEN_COPIED_LINK_TODAY_EXTENSION)
               url:_pasteURL];

  } else {
    base::WeakNSObject<TodayViewController> weakSelf(self);
    URLActionBlock action = ^(NSString* url) {
      [weakSelf openClipboardURLInChrome:url];
    };
    cell = [[URLTableCell alloc]
          initWithTitle:l10n_util::GetNSString(
                            IDS_IOS_OPEN_COPIED_LINK_TODAY_EXTENSION)
                    url:_pasteURL
                   icon:@"todayview_clipboard"
              leftInset:_defaultLeadingMarginInset
        reuseIdentifier:pasteboardReusableID
                  block:action];
    cell.selectionStyle = UITableViewCellSelectionStyleNone;
  }
  return cell;
}

- (URLTableCell*)cellForShowMore {
  NSString* showMoreReusableID = @"ShowMoreCell";
  URLTableCell* cell = base::mac::ObjCCast<URLTableCell>(
      [_urlsTable dequeueReusableCellWithIdentifier:showMoreReusableID]);
  NSString* title = l10n_util::GetNSString(
      IDS_IOS_PYSICAL_WEB_TODAY_EXTENSION_SHOW_MORE_BEACONS);
  if (cell) {
    [cell setTitle:title url:@""];
  } else {
    base::WeakNSObject<TodayViewController> weakSelf(self);
    URLActionBlock action = ^(NSString* url) {
      [weakSelf setDisplayAllPhysicalWebItems:YES];
      [weakSelf refreshWidget];
    };
    cell = [[URLTableCell alloc] initWithTitle:title
                                           url:@""
                                          icon:@""
                                     leftInset:_defaultLeadingMarginInset
                               reuseIdentifier:showMoreReusableID
                                         block:action];
    cell.selectionStyle = UITableViewCellSelectionStyleNone;
  }
  return cell;
}

- (URLTableCell*)cellForPhysicalWebURLAtIndex:(NSInteger)index {
  NSString* physicalWebReusableID = @"PhysicalWebCell";
  URLTableCell* cell = base::mac::ObjCCast<URLTableCell>(
      [_urlsTable dequeueReusableCellWithIdentifier:physicalWebReusableID]);
  PhysicalWebDevice* device = [[_scanner devices] objectAtIndex:index];
  if (cell) {
    [cell setTitle:[device title] url:[[device url] absoluteString]];
  } else {
    base::WeakNSObject<TodayViewController> weakSelf(self);
    URLActionBlock action = ^(NSString* url) {
      [weakSelf openPhysicalWebURLInChrome:url];
    };
    cell = [[URLTableCell alloc] initWithTitle:[device title]
                                           url:[[device url] absoluteString]
                                          icon:@"todayview_physical_web"
                                     leftInset:_defaultLeadingMarginInset
                               reuseIdentifier:physicalWebReusableID
                                         block:action];
    cell.selectionStyle = UITableViewCellSelectionStyleNone;
  }
  return cell;
}

- (UITableViewCell*)tableView:(UITableView*)tableView
        cellForRowAtIndexPath:(NSIndexPath*)indexPath {
  DCHECK(tableView == _urlsTable.get());
  NSInteger indexRequested = [indexPath row];
  NSInteger lastRowIndex =
      [self tableView:tableView numberOfRowsInSection:0] - 1;

  DCHECK(indexRequested >= 0 && indexRequested <= lastRowIndex);

  URLTableCell* cell = nil;
  if (_pasteURL) {
    if (indexRequested == 0) {
      cell = [self cellForPasteboardURL];
    }
    indexRequested--;
  }
  if (!cell && indexRequested >= kMaxNumberOfPhysicalWebItem &&
      !_displayAllPhysicalWebItems) {
    cell = [self cellForShowMore];
  }
  if (!cell) {
    cell = [self cellForPhysicalWebURLAtIndex:indexRequested];
  }
  [cell setSeparatorVisible:[indexPath row] != lastRowIndex ||
                            _currentFooterLabel == PW_OPTIN_DIALOG];
  return cell;
}

#pragma mark - NCWidgetProviding

- (void)widgetActiveDisplayModeDidChange:(NCWidgetDisplayMode)activeDisplayMode
                         withMaximumSize:(CGSize)maxSize {
  if (activeDisplayMode == NCWidgetDisplayModeExpanded) {
    // If in NCWidgetDisplayModeExpanded mode, we can change the size of the
    // widget.
    [self setHeight:[self widgetHeight]];
  } else {
    // If in NCWidgetDisplayModeCompact mode, the size has to be
    // |NCWidgetDisplayModeCompact.maxsize|. Set the preferredContentSize so
    // next time we want to check the size, the value is correct.
    // Directly call |setPreferredContentSize:| as widget is not expandable at
    // this time.
    [self setPreferredContentSize:maxSize];
  }
}

- (void)widgetPerformUpdateWithCompletionHandler:
    (void (^)(NCUpdateResult))completionHandler {
  completionHandler(NCUpdateResultNewData);
}

- (UIEdgeInsets)widgetMarginInsetsForProposedMarginInsets:
    (UIEdgeInsets)defaultMarginInsets {
  DCHECK(!base::ios::IsRunningOnIOS10OrLater());
  if (!UIEdgeInsetsEqualToEdgeInsets(defaultMarginInsets, UIEdgeInsetsZero)) {
    if (ui_util::IsRTL()) {
      _defaultLeadingMarginInset = defaultMarginInsets.right;
    } else {
      _defaultLeadingMarginInset = defaultMarginInsets.left;
    }
  }
  return UIEdgeInsetsZero;
}

@end
