// Copyright 2018 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 "ui/accelerated_widget_mac/ca_transaction_observer.h"

#include "base/no_destructor.h"
#include "base/time/default_tick_clock.h"
#include "base/trace_event/trace_event.h"
#include "ui/accelerated_widget_mac/window_resize_helper_mac.h"

#import <AppKit/AppKit.h>
#import <CoreFoundation/CoreFoundation.h>
#import <QuartzCore/QuartzCore.h>

typedef NS_ENUM(unsigned int, CATransactionPhase) {
  kCATransactionPhasePreLayout,
  kCATransactionPhasePreCommit,
  kCATransactionPhasePostCommit,
};

@interface CATransaction ()
+ (void)addCommitHandler:(void (^)(void))block
                forPhase:(CATransactionPhase)phase;
@end

namespace ui {

namespace {
NSString* kRunLoopMode = @"Chrome CATransactionCoordinator commit handler";
constexpr auto kPostCommitTimeout = base::TimeDelta::FromMilliseconds(50);
}  // namespace

CATransactionCoordinator& CATransactionCoordinator::Get() {
  static base::NoDestructor<CATransactionCoordinator> instance;
  return *instance;
}

void CATransactionCoordinator::SynchronizeImpl() {
  static bool registeredRunLoopMode = false;
  if (!registeredRunLoopMode) {
    CFRunLoopAddCommonMode(CFRunLoopGetCurrent(),
                           static_cast<CFStringRef>(kRunLoopMode));
    registeredRunLoopMode = true;
  }
  if (active_)
    return;
  active_ = true;

  for (auto& observer : post_commit_observers_)
    observer->OnActivateForTransaction();

  [CATransaction addCommitHandler:^{
    PreCommitHandler();
  }
                         forPhase:kCATransactionPhasePreCommit];

  [CATransaction addCommitHandler:^{
    PostCommitHandler();
  }
                         forPhase:kCATransactionPhasePostCommit];
}

void CATransactionCoordinator::PreCommitHandler() {
  TRACE_EVENT0("ui", "CATransactionCoordinator: pre-commit handler");
  auto* clock = base::DefaultTickClock::GetInstance();
  const base::TimeTicks start_time = clock->NowTicks();
  while (true) {
    bool continue_waiting = false;
    base::TimeTicks deadline = start_time;
    for (auto& observer : pre_commit_observers_) {
      if (observer.ShouldWaitInPreCommit()) {
        continue_waiting = true;
        deadline = std::max(deadline, start_time + observer.PreCommitTimeout());
      }
    }
    if (!continue_waiting)
      break;  // success

    base::TimeDelta time_left = deadline - clock->NowTicks();
    if (time_left <= base::TimeDelta::FromSeconds(0))
      break;  // timeout

    ui::WindowResizeHelperMac::Get()->WaitForSingleTaskToRun(time_left);
  }
}

void CATransactionCoordinator::PostCommitHandler() {
  TRACE_EVENT0("ui", "CATransactionCoordinator: post-commit handler");

  for (auto& observer : post_commit_observers_)
    observer->OnEnterPostCommit();

  auto* clock = base::DefaultTickClock::GetInstance();
  const base::TimeTicks deadline = clock->NowTicks() + kPostCommitTimeout;
  while (true) {
    bool continue_waiting = std::any_of(
        post_commit_observers_.begin(), post_commit_observers_.end(),
        std::mem_fn(&PostCommitObserver::ShouldWaitInPostCommit));
    if (!continue_waiting)
      break;  // success

    base::TimeDelta time_left = deadline - clock->NowTicks();
    if (time_left <= base::TimeDelta::FromSeconds(0))
      break;  // timeout

    ui::WindowResizeHelperMac::Get()->WaitForSingleTaskToRun(time_left);
  }
  active_ = false;
}

CATransactionCoordinator::CATransactionCoordinator() = default;
CATransactionCoordinator::~CATransactionCoordinator() = default;

void CATransactionCoordinator::Synchronize() {
  if (disabled_for_testing_)
    return;
  SynchronizeImpl();
}

void CATransactionCoordinator::AddPreCommitObserver(
    PreCommitObserver* observer) {
  pre_commit_observers_.AddObserver(observer);
}

void CATransactionCoordinator::RemovePreCommitObserver(
    PreCommitObserver* observer) {
  pre_commit_observers_.RemoveObserver(observer);
}

void CATransactionCoordinator::AddPostCommitObserver(
    scoped_refptr<PostCommitObserver> observer) {
  DCHECK(!post_commit_observers_.count(observer));
  post_commit_observers_.insert(std::move(observer));
}

void CATransactionCoordinator::RemovePostCommitObserver(
    scoped_refptr<PostCommitObserver> observer) {
  DCHECK(post_commit_observers_.count(observer));
  post_commit_observers_.erase(std::move(observer));
}

}  // namespace ui
