﻿namespace Stove.StoveSDK
{
    using System;
    using System.Collections.Generic;
    using MiniJSON;

    /**
     * The result of the API call.
     *
     * It consists of [domain], [errorCode], [errorMessage]
     */
    public class Result
    {
        private const string SuccessDomain = "com.stove.success";
        private const string CancelDomain = "com.stove.cancel";
        private const string ServerErrorDomain = "com.stove.server";

        /**
         * Group of error code.
         *
         * In case of network, it will be displayed as 'com.stove.base.network'.
         * @since 2.0.0
         */
        public string Domain { get; }

        /**
         * Error code.
         *
         * If the result is successful, it is displayed as [Success].
         * @since 2.0.0
         */
        public int ErrorCode { get; }

        /**
         * Error message.
         *
         * If the result is successful, 'Success' is displayed.
         * @since 2.0.0
         */
        public string ErrorMessage { get; }

        /**
         * Additional information.
         * @since 2.0.0
         */
        public Dictionary<string, string> UserInfo { get; set; }

        /**
         * Whether API call is successful.
         * @return API call is successful.
         * @since 2.0.0
         */
        public bool IsSuccessful { get { return Domain.Equals(SuccessDomain); } }

        /**
         * Whether API call is canceled.
         * @return API call is canceled.
         * @since 2.0.0
         */
        public bool IsCanceled { get { return Domain.Equals(CancelDomain); } }

        /**
         * Whether API call is servers' error.
         * @return API call is servers' error.
         * @since 2.0.0
         */
        public bool IsServerError { get { return Domain.Equals(ServerErrorDomain); } }

        public Result(string domain, int errorCode, string errorMessage, Dictionary<string, string> userInfo = null)
        {
            Domain = domain;
            ErrorCode = errorCode;
            ErrorMessage = errorMessage;
            UserInfo = userInfo;
        }

        /**
         * Dictionary serialization.
         * @since 2.0.0
         */
        public Result(Dictionary<string, object> dictionary)
        {
            Domain = dictionary["domain"] as string;
            ErrorCode = Convert.ToInt32(dictionary["errorCode"]);
            ErrorMessage = dictionary["errorMessage"] as string;
            if (dictionary.ContainsKey("userInfo"))
            {
                Dictionary<string, string> userinfo = new Dictionary<string, string>();
                Dictionary<string, object> userInfoObject = dictionary["userInfo"] as Dictionary<string, object>;
                foreach (KeyValuePair<string, object> keyValuePair in userInfoObject)
                {
                    userinfo.Add(keyValuePair.Key, keyValuePair.Value as string);
                }
                UserInfo = userinfo;
            }
        }

        /**
         * Dictionary deserialization.
         * @since 2.0.0
         */
        public Dictionary<string, object> ToDictionary()
        {
            Dictionary<string, object> dictionary = new Dictionary<string, object>();
            dictionary.Add("domain", Domain);
            dictionary.Add("errorCode", ErrorCode);
            dictionary.Add("errorMessage", ErrorMessage);

            if (UserInfo != null)
            {
                dictionary.Add("userInfo", UserInfo);
            }

            return dictionary;
        }

        /**
         * JSON serialization.
         * @since 2.0.0
         */
        public string ToJSONString()
        {
            Dictionary<string, object> dictionary = ToDictionary();

            return Json.Serialize(dictionary);
        }

        public override string ToString()
        {
            string userInfoString = "";
            if (UserInfo != null)
            {
                userInfoString = Json.Serialize(UserInfo);
            }
            return "Result(Domain='" + Domain + "', ErrorCode=" + ErrorCode + ", ErrorMessage='" + ErrorMessage + "', UserInfo=" + userInfoString + ")";
        }
    }

}
