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

#include "content/browser/theme_helper_mac.h"

#import <Carbon/Carbon.h>
#import <Cocoa/Cocoa.h>

#include "base/bind.h"
#include "base/callback.h"
#include "base/command_line.h"
#include "base/mac/mac_util.h"
#include "base/mac/scoped_nsobject.h"
#include "base/strings/sys_string_conversions.h"
#include "content/browser/renderer_host/render_process_host_impl.h"
#include "content/browser/renderer_host/render_widget_host_impl.h"
#include "content/common/renderer.mojom.h"
#include "content/common/view_messages.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/notification_service.h"
#include "content/public/browser/notification_types.h"
#include "content/public/browser/render_process_host.h"
#include "content/public/browser/render_view_host.h"
#include "content/public/browser/render_widget_host_iterator.h"
#include "content/public/common/content_switches.h"
#include "ui/gfx/scoped_ns_graphics_context_save_gstate_mac.h"

using content::RenderProcessHost;
using content::RenderProcessHostImpl;
using content::ThemeHelperMac;

namespace {

blink::WebScrollbarButtonsPlacement GetButtonPlacement() {
  NSString* scrollbar_variant = [[NSUserDefaults standardUserDefaults]
      objectForKey:@"AppleScrollBarVariant"];
  if ([scrollbar_variant isEqualToString:@"Single"])
    return blink::kWebScrollbarButtonsPlacementSingle;
  else if ([scrollbar_variant isEqualToString:@"DoubleMin"])
    return blink::kWebScrollbarButtonsPlacementDoubleStart;
  else if ([scrollbar_variant isEqualToString:@"DoubleBoth"])
    return blink::kWebScrollbarButtonsPlacementDoubleBoth;
  else
    return blink::kWebScrollbarButtonsPlacementDoubleEnd;
}

void FillScrollbarThemeParams(
    content::mojom::UpdateScrollbarThemeParams* params) {
  DCHECK_CURRENTLY_ON(content::BrowserThread::UI);

  NSUserDefaults* defaults = [NSUserDefaults standardUserDefaults];
  [defaults synchronize];

  params->initial_button_delay =
      [defaults floatForKey:@"NSScrollerButtonDelay"];
  params->autoscroll_button_delay =
      [defaults floatForKey:@"NSScrollerButtonPeriod"];
  params->jump_on_track_click =
      [defaults boolForKey:@"AppleScrollerPagingBehavior"];
  params->preferred_scroller_style =
      ThemeHelperMac::GetPreferredScrollerStyle();
  params->button_placement = GetButtonPlacement();

  id rubber_band_value = [defaults objectForKey:@"NSScrollViewRubberbanding"];
  params->scroll_view_rubber_banding =
      rubber_band_value ? [rubber_band_value boolValue] : YES;
}

void SendSystemColorsChangedMessage(content::mojom::Renderer* renderer) {
  DCHECK_CURRENTLY_ON(content::BrowserThread::UI);

  NSUserDefaults* defaults = [NSUserDefaults standardUserDefaults];
  [defaults synchronize];

  renderer->OnSystemColorsChanged(
      [[defaults stringForKey:@"AppleAquaColorVariant"] intValue],
      base::SysNSStringToUTF8(
          [defaults stringForKey:@"AppleHighlightedTextColor"]),
      base::SysNSStringToUTF8(
          [defaults stringForKey:@"AppleHighlightColor"]));
}

SkColor NSColorToSkColor(NSColor* color) {
  NSColor* color_in_color_space =
      [color colorUsingColorSpace:[NSColorSpace sRGBColorSpace]];
  if (color_in_color_space) {
    // Use nextafter() to avoid rounding colors in a way that could be off-by-
    // one. See https://bugs.webkit.org/show_bug.cgi?id=6129.
    static const double kScaleFactor = nextafter(256.0, 0.0);
    return SkColorSetARGB(
        static_cast<int>(kScaleFactor * [color_in_color_space alphaComponent]),
        static_cast<int>(kScaleFactor * [color_in_color_space redComponent]),
        static_cast<int>(kScaleFactor * [color_in_color_space greenComponent]),
        static_cast<int>(kScaleFactor * [color_in_color_space blueComponent]));
  }

  // This conversion above can fail if the NSColor in question is an
  // NSPatternColor (as many system colors are). These colors are actually a
  // repeating pattern not just a solid color. To work around this we simply
  // draw a 1x1 image of the color and use that pixel's color. It might be
  // better to use an average of the colors in the pattern instead.
  base::scoped_nsobject<NSBitmapImageRep> offscreen_rep(
      [[NSBitmapImageRep alloc] initWithBitmapDataPlanes:nil
                                              pixelsWide:1
                                              pixelsHigh:1
                                           bitsPerSample:8
                                         samplesPerPixel:4
                                                hasAlpha:YES
                                                isPlanar:NO
                                          colorSpaceName:NSDeviceRGBColorSpace
                                             bytesPerRow:4
                                            bitsPerPixel:32]);

  {
    gfx::ScopedNSGraphicsContextSaveGState gstate;
    [NSGraphicsContext
        setCurrentContext:[NSGraphicsContext
                              graphicsContextWithBitmapImageRep:offscreen_rep]];
    [color set];
    NSRectFill(NSMakeRect(0, 0, 1, 1));
  }

  NSUInteger pixel[4];
  [offscreen_rep getPixel:pixel atX:0 y:0];
  // This recursive call will not recurse again, because the color space
  // the second time around is NSDeviceRGBColorSpace.
  return NSColorToSkColor([NSColor colorWithDeviceRed:pixel[0] / 255.
                                                green:pixel[1] / 255.
                                                 blue:pixel[2] / 255.
                                                alpha:1.]);
}

SkColor MenuBackgroundColor() {
  base::scoped_nsobject<NSBitmapImageRep> offscreen_rep(
      [[NSBitmapImageRep alloc] initWithBitmapDataPlanes:nil
                                              pixelsWide:1
                                              pixelsHigh:1
                                           bitsPerSample:8
                                         samplesPerPixel:4
                                                hasAlpha:YES
                                                isPlanar:NO
                                          colorSpaceName:NSDeviceRGBColorSpace
                                             bytesPerRow:4
                                            bitsPerPixel:32]);

  CGContextRef context = static_cast<CGContextRef>([[NSGraphicsContext
      graphicsContextWithBitmapImageRep:offscreen_rep] graphicsPort]);
  CGRect rect = CGRectMake(0, 0, 1, 1);
  HIThemeMenuDrawInfo draw_info;
  draw_info.version = 0;
  draw_info.menuType = kThemeMenuTypePopUp;
  HIThemeDrawMenuBackground(&rect, &draw_info, context,
                            kHIThemeOrientationInverted);

  NSUInteger pixel[4];
  [offscreen_rep getPixel:pixel atX:0 y:0];
  return NSColorToSkColor([NSColor colorWithDeviceRed:pixel[0] / 255.
                                                green:pixel[1] / 255.
                                                 blue:pixel[2] / 255.
                                                alpha:1.]);
}

} // namespace

@interface SystemThemeObserver : NSObject {
  base::RepeatingClosure colorsChangedCallback_;
}

- (instancetype)initWithColorsChangedCallback:
    (base::RepeatingClosure)colorsChangedCallback;
- (void)appearancePrefsChanged:(NSNotification*)notification;
- (void)behaviorPrefsChanged:(NSNotification*)notification;
- (void)notifyPrefsChangedWithRedraw:(BOOL)redraw;

@end

@implementation SystemThemeObserver

- (instancetype)initWithColorsChangedCallback:
    (base::RepeatingClosure)colorsChangedCallback {
  if (!(self = [super init])) {
    return nil;
  }

  colorsChangedCallback_ = std::move(colorsChangedCallback);

  NSDistributedNotificationCenter* distributedCenter =
      [NSDistributedNotificationCenter defaultCenter];
  [distributedCenter addObserver:self
                        selector:@selector(appearancePrefsChanged:)
                            name:@"AppleAquaScrollBarVariantChanged"
                          object:nil
               suspensionBehavior:
                   NSNotificationSuspensionBehaviorDeliverImmediately];

  [distributedCenter addObserver:self
                        selector:@selector(behaviorPrefsChanged:)
                            name:@"AppleNoRedisplayAppearancePreferenceChanged"
                          object:nil
              suspensionBehavior:NSNotificationSuspensionBehaviorCoalesce];

  [distributedCenter addObserver:self
                        selector:@selector(behaviorPrefsChanged:)
                            name:@"NSScrollAnimationEnabled"
                          object:nil
              suspensionBehavior:NSNotificationSuspensionBehaviorCoalesce];

  [distributedCenter addObserver:self
                        selector:@selector(appearancePrefsChanged:)
                            name:@"AppleScrollBarVariant"
                          object:nil
              suspensionBehavior:
                  NSNotificationSuspensionBehaviorDeliverImmediately];

  [distributedCenter
             addObserver:self
                selector:@selector(behaviorPrefsChanged:)
                    name:@"NSScrollViewRubberbanding"
                  object:nil
      suspensionBehavior:NSNotificationSuspensionBehaviorDeliverImmediately];

  // In single-process mode, renderers will catch these notifications
  // themselves and listening for them here may trigger the DCHECK in Observe().
  if (!base::CommandLine::ForCurrentProcess()->HasSwitch(
          switches::kSingleProcess)) {
    NSNotificationCenter* center = [NSNotificationCenter defaultCenter];

    [center addObserver:self
               selector:@selector(behaviorPrefsChanged:)
                   name:NSPreferredScrollerStyleDidChangeNotification
                 object:nil];

    [center addObserver:self
               selector:@selector(systemColorsChanged:)
                   name:NSSystemColorsDidChangeNotification
                 object:nil];
  }

  return self;
}

- (void)dealloc {
  [[NSDistributedNotificationCenter defaultCenter] removeObserver:self];
  [super dealloc];
}

- (void)appearancePrefsChanged:(NSNotification*)notification {
  [self notifyPrefsChangedWithRedraw:YES];
}

- (void)behaviorPrefsChanged:(NSNotification*)notification {
  [self notifyPrefsChangedWithRedraw:NO];
}

- (void)systemColorsChanged:(NSNotification*)notification {
  colorsChangedCallback_.Run();

  for (RenderProcessHost::iterator it(RenderProcessHost::AllHostsIterator());
       !it.IsAtEnd();
       it.Advance()) {
    SendSystemColorsChangedMessage(
        it.GetCurrentValue()->GetRendererInterface());
  }
}

- (void)notifyPrefsChangedWithRedraw:(BOOL)redraw {
  for (RenderProcessHost::iterator it(RenderProcessHost::AllHostsIterator());
       !it.IsAtEnd();
       it.Advance()) {
    content::mojom::UpdateScrollbarThemeParamsPtr params =
        content::mojom::UpdateScrollbarThemeParams::New();
    FillScrollbarThemeParams(params.get());
    params->redraw = redraw;
    RenderProcessHostImpl* rphi =
        static_cast<RenderProcessHostImpl*>(it.GetCurrentValue());
    rphi->GetRendererInterface()->UpdateScrollbarTheme(std::move(params));
  }

  std::unique_ptr<content::RenderWidgetHostIterator> all_widgets(
      content::RenderWidgetHostImpl::GetAllRenderWidgetHosts());
  while (content::RenderWidgetHost* widget = all_widgets->GetNextHost()) {
    content::RenderViewHost* rvh = content::RenderViewHost::From(widget);
    if (!rvh)
      continue;

    rvh->OnWebkitPreferencesChanged();
  }
}

@end

namespace content {

// static
ThemeHelperMac* ThemeHelperMac::GetInstance() {
  static ThemeHelperMac* instance = new ThemeHelperMac();
  return instance;
}

// static
blink::ScrollerStyle ThemeHelperMac::GetPreferredScrollerStyle() {
  return static_cast<blink::ScrollerStyle>([NSScroller preferredScrollerStyle]);
}

base::ReadOnlySharedMemoryRegion
ThemeHelperMac::DuplicateReadOnlyColorMapRegion() {
  return read_only_color_map_.Duplicate();
}

ThemeHelperMac::ThemeHelperMac() {
  // Allocate a region for the SkColor value table and map it.
  auto writable_region = base::WritableSharedMemoryRegion::Create(
      sizeof(SkColor) * blink::kMacSystemColorIDCount);
  writable_color_map_ = writable_region.Map();
  // Downgrade the region to read-only after it has been mapped.
  read_only_color_map_ = base::WritableSharedMemoryRegion::ConvertToReadOnly(
      std::move(writable_region));
  // Store the current color scheme into the table.
  LoadSystemColors();

  theme_observer_ = [[SystemThemeObserver alloc]
      initWithColorsChangedCallback:base::BindRepeating(
                                        &ThemeHelperMac::LoadSystemColors,
                                        base::Unretained(this))];
  registrar_.Add(this,
                 NOTIFICATION_RENDERER_PROCESS_CREATED,
                 NotificationService::AllSources());
}

ThemeHelperMac::~ThemeHelperMac() {
  [theme_observer_ release];
}

void ThemeHelperMac::LoadSystemColors() {
  base::span<SkColor> values = writable_color_map_.GetMemoryAsSpan<SkColor>(
      blink::kMacSystemColorIDCount);
  // Ensure light mode appearance in web content even if the topchrome is in
  // dark mode.
  // TODO(lgrey): Add a second map for content dark mode for the
  // `prefers-color-scheme` media query: https://crbug.com/889087.
  NSAppearance* savedAppearance;
  if (@available(macOS 10.14, *)) {
    savedAppearance = [NSAppearance currentAppearance];
    [NSAppearance
        setCurrentAppearance:[NSAppearance
                                 appearanceNamed:NSAppearanceNameAqua]];
  }
  for (size_t i = 0; i < blink::kMacSystemColorIDCount; ++i) {
    blink::MacSystemColorID color_id = static_cast<blink::MacSystemColorID>(i);
    switch (color_id) {
      case blink::MacSystemColorID::kAlternateSelectedControl:
        values[i] = NSColorToSkColor([NSColor alternateSelectedControlColor]);
        break;
      case blink::MacSystemColorID::kControlBackground:
        values[i] = NSColorToSkColor([NSColor controlBackgroundColor]);
        break;
      case blink::MacSystemColorID::kControlDarkShadow:
        values[i] = NSColorToSkColor([NSColor controlDarkShadowColor]);
        break;
      case blink::MacSystemColorID::kControlHighlight:
        values[i] = NSColorToSkColor([NSColor controlHighlightColor]);
        break;
      case blink::MacSystemColorID::kControlLightHighlight:
        values[i] = NSColorToSkColor([NSColor controlLightHighlightColor]);
        break;
      case blink::MacSystemColorID::kControlShadow:
        values[i] = NSColorToSkColor([NSColor controlShadowColor]);
        break;
      case blink::MacSystemColorID::kControlText:
        values[i] = NSColorToSkColor([NSColor controlTextColor]);
        break;
      case blink::MacSystemColorID::kDisabledControlText:
        values[i] = NSColorToSkColor([NSColor disabledControlTextColor]);
        break;
      case blink::MacSystemColorID::kHeader:
        values[i] = NSColorToSkColor([NSColor headerColor]);
        break;
      case blink::MacSystemColorID::kHighlight:
        values[i] = NSColorToSkColor([NSColor highlightColor]);
        break;
      case blink::MacSystemColorID::kKeyboardFocusIndicator:
        values[i] = NSColorToSkColor([NSColor keyboardFocusIndicatorColor]);
        break;
      case blink::MacSystemColorID::kMenuBackground:
        values[i] = MenuBackgroundColor();
        break;
      case blink::MacSystemColorID::kScrollBar:
        values[i] = NSColorToSkColor([NSColor scrollBarColor]);
        break;
      case blink::MacSystemColorID::kSecondarySelectedControl:
        values[i] = NSColorToSkColor([NSColor secondarySelectedControlColor]);
        break;
      case blink::MacSystemColorID::kSelectedMenuItemText:
        values[i] = NSColorToSkColor([NSColor selectedMenuItemTextColor]);
        break;
      case blink::MacSystemColorID::kSelectedText:
        values[i] = NSColorToSkColor([NSColor selectedTextColor]);
        break;
      case blink::MacSystemColorID::kSelectedTextBackground:
        values[i] = NSColorToSkColor([NSColor selectedTextBackgroundColor]);
        break;
      case blink::MacSystemColorID::kShadow:
        values[i] = NSColorToSkColor([NSColor shadowColor]);
        break;
      case blink::MacSystemColorID::kText:
        values[i] = NSColorToSkColor([NSColor textColor]);
        break;
      case blink::MacSystemColorID::kWindowBackground:
        values[i] = NSColorToSkColor([NSColor windowBackgroundColor]);
        break;
      case blink::MacSystemColorID::kWindowFrame:
        values[i] = NSColorToSkColor([NSColor windowFrameColor]);
        break;
      case blink::MacSystemColorID::kWindowFrameText:
        values[i] = NSColorToSkColor([NSColor windowFrameTextColor]);
        break;
      case blink::MacSystemColorID::kCount:
        NOTREACHED();
        break;
    }
  }
  if (@available(macOS 10.14, *)) {
    [NSAppearance setCurrentAppearance:savedAppearance];
  }
}

void ThemeHelperMac::Observe(int type,
                             const NotificationSource& source,
                             const NotificationDetails& details) {
  DCHECK_EQ(NOTIFICATION_RENDERER_PROCESS_CREATED, type);

  // When a new RenderProcess is created, send it the initial preference
  // parameters.
  content::mojom::UpdateScrollbarThemeParamsPtr params =
      content::mojom::UpdateScrollbarThemeParams::New();
  FillScrollbarThemeParams(params.get());
  params->redraw = false;

  RenderProcessHostImpl* rphi =
      Source<content::RenderProcessHostImpl>(source).ptr();
  content::mojom::Renderer* renderer = rphi->GetRendererInterface();
  renderer->UpdateScrollbarTheme(std::move(params));
  SendSystemColorsChangedMessage(renderer);
}

}  // namespace content
