using Apewer.Internals;
using System;
using System.Collections.Generic;
using System.Text;

namespace Apewer
{

    /// <summary>结果状态,Code 为零时表示正常,Code 0 与 NULL 相等。</summary>
    [Serializable]
    public class Result
    {

        private int _code;
        private string _message;

        /// <summary>代码。</summary>
        public int Code { get => _code; protected set => _code = value; }

        /// <summary>消息。</summary>
        public string Message { get => _message; protected set => _message = value; }

        /// <summary>创建实例:Code = 0,Message = NULL。</summary>
        public Result() { }

        /// <summary>创建实例。</summary>
        public Result(int code, string message = null)
        {
            _code = code;
            _message = message;
        }

        /// <summary>创建实例:Code = 0。</summary>
        public Result(string message, int code = 0)
        {
            _code = code;
            _message = message;
        }

        /// <summary></summary>
        public override string ToString()
        {
            if (string.IsNullOrEmpty(_message)) return Code.ToString();
            if (Code == 0) return _message;
            return Code.ToString() + "|" + _message;
        }

        #region 运算符。

        /// <summary>获取 Code。</summary>
        public static implicit operator int(Result result) => result == null ? 0 : result._code;

        /// <summary>ToString</summary>
        public static implicit operator string(Result result) => result == null ? null : result.ToString();

        #endregion

    }

    /// <summary>装箱返回结果,T 不适用于 System.String。</summary>
    [Serializable]
    public class Result<T> : Result, IDisposable
    {

        private T _value;
        private bool _has = false;

        /// <summary>对象。</summary>
        public T Value { get => _value; set => Set(value); }

        /// <summary>含有实体对象。</summary>
        public bool HasValue { get => _has; }

        /// <summary>执行与释放或重置非托管资源关联的应用程序定义的任务。</summary>
        public void Dispose() => RuntimeUtility.Dispose(Value);

        /// <summary>创建实例:Code = 0,Message = NULL,Value = Default。</summary>
        public Result() { }

        /// <summary>创建实例:Code = 0,Message = NULL。</summary>
        public Result(T value) => Set(value);

        /// <summary>创建实例:Value = Default。</summary>
        public Result(string message, int code = 0) : base(message, code) { }

        /// <summary>创建实例:Value = Default。</summary>
        public Result(int code, string message = null) : base(code, message) { }

        /// <summary>创建实例:Value = Default。</summary>
        public Result(Exception exception, int code = 0) : base(RuntimeUtility.Message(exception), code) { }

        /// <summary>创建实例:Value = Default。</summary>
        public Result(int code, Exception exception = null) : base(code, RuntimeUtility.Message(exception)) { }

        private void Set(T value)
        {
            _value = value;
            _has = typeof(T).IsValueType ? true : (value != null);
        }

        #region 运算符。

        /// <summary>含有实体对象。</summary>
        public static implicit operator bool(Result<T> result) => result == null ? false : result._has;

        #endregion

        #region 扩展方法。

        internal static Result<TDst> As<TSrc, TDst>(Result<TSrc> source) where TDst : TSrc
        {
            if (source == null) return null;
            var destination = new Result<TDst>();
            destination.Code = source.Code;
            destination.Message = source.Message;
            if (source._has)
            {
                var maybe = source._value is TDst;
                try { destination.Set((TDst)source._value); } catch { }
            }
            return destination;
        }

        #endregion

    }

}