// Copyright (c) ServiceStack, Inc. All Rights Reserved.
// License: https://raw.github.com/ServiceStack/ServiceStack/master/license.txt

using System;
using System.Collections.Generic;
using ServiceStack.Text;
using ServiceStack.Validation;
using static System.String;

namespace ServiceStack
{
    public static class ResponseStatusUtils
    {
        /// <summary>
        /// Creates the error response from the values provided.
        /// 
        /// If the errorCode is empty it will use the first validation error code, 
        /// if there is none it will throw an error.
        /// </summary>
        /// <param name="errorCode">The error code.</param>
        /// <param name="errorMessage">The error message.</param>
        /// <param name="validationErrors">The validation errors.</param>
        /// <returns></returns>
        public static ResponseStatus CreateResponseStatus(string errorCode, string errorMessage, IEnumerable<ValidationErrorField> validationErrors=null)
        {
            var to = new ResponseStatus {
                ErrorCode = errorCode,
                Message = errorMessage,
                Errors = [],
            };
            if (validationErrors != null)
            {
                foreach (var validationError in validationErrors)
                {
                    var error = new ResponseError {
                        ErrorCode = validationError.ErrorCode,
                        FieldName = validationError.FieldName,
                        Message = validationError.ErrorMessage,
                        Meta = validationError.Meta,
                    };
                    to.Errors.Add(error);

                    if (IsNullOrEmpty(to.ErrorCode))
                    {
                        to.ErrorCode = validationError.ErrorCode;
                    }
                    if (IsNullOrEmpty(to.Message))
                    {
                        to.Message = validationError.ErrorMessage;
                    }
                }
            }

            if (IsNullOrEmpty(errorCode) && IsNullOrEmpty(to.ErrorCode))
                throw new ArgumentException("Cannot create a valid error response with a en empty errorCode and an empty validationError list");

            return to;
        }

        public static string GetDetailedError(this ResponseStatus status)
        {
            var sb = StringBuilderCache.Allocate();
            sb.AppendLine($"{status.ErrorCode} {status.Message}");
            foreach (var error in status.Errors.OrEmpty())
            {
                sb.AppendLine($" - {error.FieldName}: {error.ErrorCode} {error.Message}");
            }
            if (!string.IsNullOrEmpty(status.StackTrace))
            {
                sb.AppendLine("StackTrace:");
                sb.AppendLine(status.StackTrace);
            }
            return StringBuilderCache.ReturnAndFree(sb);
        }
    }

}