using System;

namespace ActorCore
{
    /// <summary>
    /// ActorID
    /// </summary>
    public struct ActorId
    {
        /// <summary>
        /// 模块Id
        /// </summary>
        public ProcessInfo Process;
        
        /// <summary>
        /// ActorType 类型
        /// </summary>
        public byte ActorTypeId;

        public byte ModuleId => Process.ModuleId;

        public byte NodeNum => Process.NodeNum;

        public ActorId(ProcessInfo process, byte actorTypeId)
        {
            this.Process = process;
            this.ActorTypeId = actorTypeId;
        }

        public ActorId(byte moduleId, byte nodeNum, byte actorTypeId)
        {
            this.Process = new ProcessInfo(moduleId, nodeNum);
            ActorTypeId = actorTypeId;
        }

        public int GetChannelId()
        {
            return ModuleId * 10 + NodeNum;
        }

        public override string ToString()
        {
            return $"{ModuleId}:{NodeNum}:{ActorTypeId}";
        }
        
        public static bool operator == (ActorId left, ActorId right)
        {
            return left.Process == right.Process && left.ActorTypeId == right.ActorTypeId;
        }

        public static bool operator !=(ActorId left, ActorId right)
        {
            return !(left == right);
        }

        public override int GetHashCode()
        {
            return ModuleId * 1000 + NodeNum * 100 + ActorTypeId;
        }
    }

    public struct ProcessInfo
    {
        /// <summary>
        /// 模块Id
        /// </summary>
        public byte ModuleId;

        /// <summary>
        /// 节点编号
        /// </summary>
        public byte NodeNum;
        
        public ProcessInfo(byte moduleId, byte nodeNum)
        {
            ModuleId = moduleId;
            NodeNum = nodeNum;
        }

        public override string ToString()
        {
            return $"{ModuleId}:{NodeNum}";
        }

        public bool Equals(ProcessInfo other)
        {
            return this.ModuleId == other.ModuleId && this.NodeNum == other.NodeNum;
        }

        public override bool Equals(object obj)
        {
            if (obj is ProcessInfo)
            {
                return Equals((ProcessInfo)obj);
            }
            return false;
        }

        public static bool operator == (ProcessInfo left, ProcessInfo right)
        {
            return left.NodeNum == right.NodeNum && left.ModuleId == right.ModuleId;
        }
        
        public static bool operator != (ProcessInfo left, ProcessInfo right)
        {
            return !(left == right);
        }
    }
}