#if UNITY_2020_3_OR_NEWER && UNITY_EDITOR_WIN
using FishNet.CodeAnalysis.Annotations;
#endif
using FishNet.Component.ColliderRollback;
using FishNet.Connection;
using FishNet.Managing;
using FishNet.Managing.Client;
using FishNet.Managing.Observing;
using FishNet.Managing.Predicting;
using FishNet.Managing.Scened;
using FishNet.Managing.Server;
using FishNet.Managing.Timing;
using FishNet.Managing.Transporting;
using FishNet.Observing;
using System;
using System.Collections.Generic;
using UnityEngine;
namespace FishNet.Object
{
    public abstract partial class NetworkBehaviour : MonoBehaviour
    {
        /// 
        /// True if the NetworkObject for this NetworkBehaviour is deinitializing.
        /// 
        public bool IsDeinitializing => _networkObjectCache.IsDeinitializing;
        /// 
        /// NetworkManager for this object.
        /// 
        public NetworkManager NetworkManager => _networkObjectCache.NetworkManager;
        /// 
        /// ServerManager for this object.
        /// 
        public ServerManager ServerManager => _networkObjectCache.ServerManager;
        /// 
        /// ClientManager for this object.
        /// 
        public ClientManager ClientManager => _networkObjectCache.ClientManager;
        /// 
        /// ObserverManager for this object.
        /// 
        public ObserverManager ObserverManager => _networkObjectCache.ObserverManager;
        /// 
        /// TransportManager for this object.
        /// 
        public TransportManager TransportManager => _networkObjectCache.TransportManager;
        /// 
        /// TimeManager for this object.
        /// 
        public TimeManager TimeManager => _networkObjectCache.TimeManager;
        /// 
        /// SceneManager for this object.
        /// 
        public SceneManager SceneManager => _networkObjectCache.SceneManager;
        /// 
        /// PredictionManager for this object.
        /// 
        public PredictionManager PredictionManager => _networkObjectCache.PredictionManager;
        /// 
        /// RollbackManager for this object.
        /// 
        public RollbackManager RollbackManager => _networkObjectCache.RollbackManager;
        /// 
        /// NetworkObserver on this object.
        /// 
        public NetworkObserver NetworkObserver => _networkObjectCache.NetworkObserver;
        /// 
        /// True if the client is active and authenticated.
        /// 
        public bool IsClient => _networkObjectCache.IsClient;
        /// 
        /// True if only the client is active and authenticated.
        /// 
        public bool IsClientOnly => _networkObjectCache.IsClientOnly;
        /// 
        /// True if server is active.
        /// 
        public bool IsServer => _networkObjectCache.IsServer;
        /// 
        /// True if only the server is active.
        /// 
        public bool IsServerOnly => _networkObjectCache.IsServerOnly;
        /// 
        /// True if client and server are active.
        /// 
        public bool IsHost => _networkObjectCache.IsHost;
        /// 
        /// True if client nor server are active.
        /// 
        public bool IsOffline => _networkObjectCache.IsOffline;
        /// 
        /// Observers for this NetworkBehaviour.
        /// 
        public HashSet Observers => _networkObjectCache.Observers;
        /// 
        /// True if the local client is the owner of this object.
        /// 
#if UNITY_2020_3_OR_NEWER && UNITY_EDITOR_WIN
        [PreventUsageInside("global::FishNet.Object.NetworkBehaviour", "OnStartServer", "")]
        [PreventUsageInside("global::FishNet.Object.NetworkBehaviour", "OnStartNetwork", " Use base.Owner.IsLocalClient instead.")]
        [PreventUsageInside("global::FishNet.Object.NetworkBehaviour", "Awake", "")]
        [PreventUsageInside("global::FishNet.Object.NetworkBehaviour", "Start", "")]
#endif
        public bool IsOwner => _networkObjectCache.IsOwner;
        /// 
        /// Owner of this object.
        /// 
        public NetworkConnection Owner
        {
            get
            {
                //Ensures a null Owner is never returned.
                if (_networkObjectCache == null)
                    return FishNet.Managing.NetworkManager.EmptyConnection;
                return _networkObjectCache.Owner;
            }
        }
        /// 
        /// ClientId for this NetworkObject owner.
        /// 
        public int OwnerId => _networkObjectCache.OwnerId;
        /// 
        /// Unique Id for this _networkObjectCache. This does not represent the object owner.
        /// 
        public int ObjectId => _networkObjectCache.ObjectId;
        /// 
        /// The local connection of the client calling this method.
        /// 
        public NetworkConnection LocalConnection => _networkObjectCache.LocalConnection;
        /// 
        /// Returns if a connection is the owner of this object.
        /// 
        /// 
        /// 
        public bool OwnerMatches(NetworkConnection connection)
        {
            return (_networkObjectCache.Owner == connection);
        }
        /// 
        /// Despawns a GameObject. Only call from the server.
        /// 
        /// GameObject to despawn.
        /// What happens to the object after being despawned.
        public void Despawn(GameObject go, DespawnType? despawnType = null)
        {
            if (!IsNetworkObjectNull(true))
                _networkObjectCache.Despawn(go, despawnType);
        }
        /// 
        /// Despawns  a NetworkObject. Only call from the server.
        /// 
        /// NetworkObject to despawn.
        /// What happens to the object after being despawned.
        public void Despawn(NetworkObject nob, DespawnType? despawnType = null)
        {
            if (!IsNetworkObjectNull(true))
                _networkObjectCache.Despawn(nob, despawnType);
        }
        /// 
        /// Despawns this _networkObjectCache. Can only be called on the server.
        /// 
        /// What happens to the object after being despawned.
        public void Despawn(DespawnType? despawnType = null)
        {
            if (!IsNetworkObjectNull(true))
                _networkObjectCache.Despawn(despawnType);
        }
        /// 
        /// Spawns an object over the network. Can only be called on the server.
        /// 
        /// GameObject instance to spawn.
        /// Connection to give ownership to.
        public void Spawn(GameObject go, NetworkConnection ownerConnection = null)
        {
            if (IsNetworkObjectNull(true))
                return;
            _networkObjectCache.Spawn(go, ownerConnection);
        }
        /// 
        /// Spawns an object over the network. Can only be called on the server.
        /// 
        /// GameObject instance to spawn.
        /// Connection to give ownership to.
        public void Spawn(NetworkObject nob, NetworkConnection ownerConnection = null)
        {
            if (IsNetworkObjectNull(true))
                return;
            _networkObjectCache.Spawn(nob, ownerConnection);
        }
        /// 
        /// Returns if NetworkObject is null.
        /// 
        /// True to throw a warning if null.
        /// 
        private bool IsNetworkObjectNull(bool warn)
        {
            bool isNull = (_networkObjectCache == null);
            if (isNull && warn)
                NetworkManager.LogWarning($"NetworkObject is null. This can occur if this object is not spawned, or initialized yet.");
            return isNull;
        }
        /// 
        /// Removes ownership from all clients.
        /// 
        public void RemoveOwnership()
        {
            _networkObjectCache.GiveOwnership(null, true);
        }
        /// 
        /// Gives ownership to newOwner.
        /// 
        /// 
        public void GiveOwnership(NetworkConnection newOwner)
        {
            _networkObjectCache.GiveOwnership(newOwner, true);
        }
        #region Registered components
        /// 
        /// Invokes an action when a specified component becomes registered. Action will invoke immediately if already registered.
        /// 
        /// Component type.
        /// Action to invoke.
        public void RegisterInvokeOnInstance(Action handler) where T : UnityEngine.Component => _networkObjectCache.RegisterInvokeOnInstance(handler);
        /// 
        /// Removes an action to be invoked when a specified component becomes registered.
        /// 
        /// Component type.
        /// Action to invoke.
        public void UnregisterInvokeOnInstance(Action handler) where T : UnityEngine.Component => _networkObjectCache.UnregisterInvokeOnInstance(handler);
        /// 
        /// Returns class of type if found within CodegenBase classes.
        /// 
        /// 
        /// 
        public T GetInstance() where T : UnityEngine.Component => _networkObjectCache.GetInstance();
        /// 
        /// Registers a new component to this NetworkManager.
        /// 
        /// Type to register.
        /// Reference of the component being registered.
        /// True to replace existing references.
        public void RegisterInstance(T component, bool replace = true) where T : UnityEngine.Component => _networkObjectCache.RegisterInstance(component, replace);
        /// 
        /// Unregisters a component from this NetworkManager.
        /// 
        /// Type to unregister.
        public void UnregisterInstance() where T : UnityEngine.Component => _networkObjectCache.UnregisterInstance();
        #endregion
    }
}