// Copyright 2019 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef IOS_CHROME_BROWSER_SHARED_COORDINATOR_SCENE_SCENE_STATE_H_
#define IOS_CHROME_BROWSER_SHARED_COORDINATOR_SCENE_SCENE_STATE_H_

#import <UIKit/UIKit.h>

#import <string_view>

#import "ios/chrome/browser/scoped_ui_blocker/ui_bundled/ui_blocker_target.h"
#import "ios/chrome/browser/shared/coordinator/scene/scene_activation_level.h"
#import "ios/chrome/browser/shared/coordinator/scene/scene_state_observer.h"
#import "ios/chrome/browser/window_activities/model/window_activity_helpers.h"

@class AppState;
@protocol BrowserProviderInterface;
@class IncognitoState;
@class LensOverlayStateNotifier;
@class ProfileState;
@protocol SceneAgent;
@class SceneController;
@class SceneLayoutState;
@class SceneState;
@protocol SceneStateAnimator;
@class SceneStatePrefs;
@class SceneUIBlockerState;
class SigninInProgress;
@class TabGridState;

// An object containing the state of a UIWindowScene. One state object
// corresponds to one scene.
// TODO(b/326186137): This class should implement BrowserProviderInterface.
@interface SceneState : NSObject <UIBlockerTarget>

// Designated initializer.
- (instancetype)init NS_DESIGNATED_INITIALIZER;

// The profile state for profile that owns this scene.
@property(nonatomic, weak) ProfileState* profileState;

// The SceneStateAnimator instance.
@property(nonatomic, weak) id<SceneStateAnimator> animator;

// The current activation level.
@property(nonatomic, assign) SceneActivationLevel activationLevel;

// The current origin of the scene.  After window creation this will be
// WindowActivityRestoredOrigin.
@property(nonatomic, assign) WindowActivityOrigin currentOrigin;

// Window for the associated scene, if any.
@property(nonatomic, weak) UIWindow* window;

// The scene object backing this scene state. It's in a 1-to-1 relationship and
// the window scene owns this object (indirectly through scene delegate).
@property(nonatomic, weak) UIWindowScene* scene;

// Connection options of `scene`, if any, from when the scene was connected.
@property(nonatomic, strong) UISceneConnectionOptions* connectionOptions;

// The interface provider associated with this scene.
@property(nonatomic, strong, readonly) id<BrowserProviderInterface>
    browserProviderInterface;

// The persistent identifier for the scene session. This should be used instead
// of -[UISceneSession persistentIdentifier].
@property(nonatomic, assign) std::string_view sceneSessionID;

// The controller for this scene.
@property(nonatomic, weak) SceneController* controller;

// When this is YES, the scene either resumed or started up in response to an
// external intent.
@property(nonatomic, assign) BOOL startupHadExternalIntent;

// URLs passed to `UIWindowSceneDelegate scene:openURLContexts:` that needs to
// be open next time the scene is activated.
// Setting the property to not nil will add the new URL contexts to the set.
// Setting the property to nil will clear the set.
@property(nonatomic) NSSet<UIOpenURLContext*>* URLContextsToOpen;

// A NSUserActivity that has been passed to
// `UISceneDelegate scene:continueUserActivity:` and needs to be opened.
@property(nonatomic) NSUserActivity* pendingUserActivity;

// YES if the UI is enabled. The browser UI objects are available when this is
// YES.
@property(nonatomic, assign) BOOL UIEnabled;

// YES if the QR scanner is visible.
@property(nonatomic, assign) BOOL QRScannerVisible;

// YES if sign-in is in progress which covers the authentication flow and the
// sign-in prompt UI.
@property(nonatomic, readonly) BOOL signinInProgress;

// Object containing the state of whether some incognito content is visible, for
// example an incognito tab or the incognito tab switcher.
@property(nonatomic, strong, readonly) IncognitoState* incognitoState;

// Object containing the state of the scene UI blocker.
@property(nonatomic, strong, readonly) SceneUIBlockerState* uiBlockerState;

// Object containing the state of the tab grid.
@property(nonatomic, strong, readonly) TabGridState* tabGridState;

// Object containing the state of the layout.
@property(nonatomic, strong, readonly) SceneLayoutState* layoutState;

// Object used to notify of changes to the LensOverlay state.
@property(nonatomic, strong, readonly)
    LensOverlayStateNotifier* lensOverlayStateNotifier;

// Object allowing access to the SceneState scoped preferences.
@property(nonatomic, strong) SceneStatePrefs* prefs;

// Adds an observer to this scene state. The observers will be notified about
// scene state changes per SceneStateObserver protocol.
- (void)addObserver:(id<SceneStateObserver>)observer;
// Removes the observer. It's safe to call this at any time, including from
// SceneStateObserver callbacks.
- (void)removeObserver:(id<SceneStateObserver>)observer;

// Adds a new agent. Agents are owned by the scene state.
- (void)addAgent:(id<SceneAgent>)agent;

// Array of all agents added to this scene state.
- (NSArray*)connectedAgents;

// Records that an extra sign-in process started. When the returned value is
// destructed, the sign-in ended.
- (std::unique_ptr<SigninInProgress>)createSigninInProgress;

@end

#endif  // IOS_CHROME_BROWSER_SHARED_COORDINATOR_SCENE_SCENE_STATE_H_
