// Copyright 2013 The Flutter Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef FLUTTER_SHELL_PLATFORM_WINDOWS_WINDOWS_LIFECYCLE_MANAGER_H_
#define FLUTTER_SHELL_PLATFORM_WINDOWS_WINDOWS_LIFECYCLE_MANAGER_H_

#include <Windows.h>

#include <cstdint>
#include <map>
#include <mutex>
#include <optional>
#include <set>

#include "flutter/shell/platform/common/app_lifecycle_state.h"

namespace flutter {

class FlutterWindowsEngine;

/// An event representing a change in window state that may update the
// application lifecycle state.
enum class WindowStateEvent {
  kShow,
  kHide,
  kFocus,
  kUnfocus,
};

/// A manager for lifecycle events of the top-level windows.
///
/// WndProc is called for window messages of the top-level Flutter window.
/// ExternalWindowMessage is called for non-flutter top-level window messages.
/// OnWindowStateEvent is called when the visibility or focus state of a window
///   is changed, including the FlutterView window.
class WindowsLifecycleManager {
 public:
  WindowsLifecycleManager(FlutterWindowsEngine* engine);
  virtual ~WindowsLifecycleManager();

  // Called when the engine is notified it should quit, e.g. by an application
  // call to `exitApplication`. When window is std::nullopt, this quits the
  // application. Otherwise, it holds the HWND of the window that initiated the
  // request, and exit_code is unused.
  virtual void Quit(std::optional<HWND> window,
                    std::optional<WPARAM> wparam,
                    std::optional<LPARAM> lparam,
                    UINT exit_code);

  // Intercept top level window WM_CLOSE message and listen to events that may
  // update the application lifecycle.
  bool WindowProc(HWND hwnd, UINT msg, WPARAM w, LPARAM l, LRESULT* result);

  // Signal to start consuming WM_CLOSE messages and sending lifecycle state
  // update messages.
  virtual void BeginProcessingLifecycle();

  // Update the app lifecycle state in response to a change in window state.
  // When the app lifecycle state actually changes, this sends a platform
  // message to the framework notifying it of the state change.
  virtual void SetLifecycleState(AppLifecycleState state);

  // Respond to a change in window state. Transitions as follows:
  // When the only visible window is hidden, transition from resumed or
  // inactive to hidden.
  // When the only focused window is unfocused, transition from resumed to
  // inactive.
  // When a window is focused, transition from inactive to resumed.
  // When a window is shown, transition from hidden to inactive.
  virtual void OnWindowStateEvent(HWND hwnd, WindowStateEvent event);

  AppLifecycleState GetLifecycleState() { return state_; }

  // Called by the engine when a non-Flutter window receives an event that may
  // alter the lifecycle state. The logic for external windows must differ from
  // that used for FlutterWindow instances, because:
  // - FlutterWindow does not receive WM_SHOW messages,
  // - When FlutterWindow receives WM_SIZE messages, wparam stores no meaningful
  //   information, whereas it usually indicates the action which changed the
  //   window size.
  // When this returns a result, the message has been consumed and should not be
  // processed further. Currently, it will always return nullopt.
  std::optional<LRESULT> ExternalWindowMessage(HWND hwnd,
                                               UINT message,
                                               WPARAM wparam,
                                               LPARAM lparam);

 protected:
  // Check the number of top-level windows associated with this process, and
  // return true only if there are 1 or fewer.
  virtual bool IsLastWindowOfProcess();

  virtual void DispatchMessage(HWND window,
                               UINT msg,
                               WPARAM wparam,
                               LPARAM lparam);

 private:
  FlutterWindowsEngine* engine_;

  std::map<std::tuple<HWND, WPARAM, LPARAM>, int> sent_close_messages_;

  bool process_lifecycle_ = false;

  std::set<HWND> visible_windows_;

  std::set<HWND> focused_windows_;

  std::mutex state_update_lock_;

  flutter::AppLifecycleState state_;
};

}  // namespace flutter

#endif  // FLUTTER_SHELL_PLATFORM_WINDOWS_WINDOWS_LIFECYCLE_MANAGER_H_
