using System;

namespace Aidlab
{
    public sealed class AidlabError
    {
        public AidlabAPI.AidlabErrorCode Code { get; }
        public string Message { get; }

        public AidlabError(AidlabAPI.AidlabErrorCode code, string message)
        {
            Code = code;
            Message = message ?? "";
        }

        public override string ToString()
        {
            return $"AidlabError(code={Code}, message={Message})";
        }
    }

    /// <summary>Why the device rejected a command.</summary>
    public enum RejectionReason : int
    {
        /// <summary>The firmware does not report the reason, or this SDK version does not know it.</summary>
        Unknown = -1,
        /// <summary>ENOENT: the device does not know the command.</summary>
        UnknownCommand = 1,
        /// <summary>EAGAIN: no free process slot.</summary>
        NoFreeSlot = 2,
        /// <summary>ENOMEM: the device is out of memory.</summary>
        OutOfMemory = 3,
        /// <summary>E2BIG: the command is too long.</summary>
        CommandTooLong = 4,
        /// <summary>EINVAL: a running service rejected the arguments.</summary>
        InvalidArgument = 5,
        /// <summary>EBUSY: the command conflicts with the device state, e.g. sync clear during a sync.</summary>
        Busy = 6,
        /// <summary>ESRCH: kill found no such process.</summary>
        NoSuchProcess = 7,
        /// <summary>EPERM: kill is not permitted.</summary>
        NotPermitted = 8,
        /// <summary>ENOTCONN: no client or a stale session.</summary>
        NotConnected = 9,
        /// <summary>ESHUTDOWN: the process manager is stopping.</summary>
        ShuttingDown = 10,
    }

    /// <summary>The device rejected a command; <see cref="Reason"/> tells why.</summary>
    public sealed class ProcessRejectedException : InvalidOperationException
    {
        public RejectionReason Reason { get; }

        public ProcessRejectedException(RejectionReason reason, string message) : base(message)
        {
            Reason = reason;
        }
    }
}
