﻿using System;
using System.ServiceModel;

namespace Hardcore.Web.Wcf
{
    class ExceptionToFaultConverter
    {
        public bool HideInner { get; set; }
        public int StringLenLim { get; set; }
        public string FaultCodeNamespace { get; set; }
        public string Source { get; set; }
        public bool IncludeExceptionDetails { get; set; }

        public FaultException Convert(Exception exception)
        {
            if (exception is FaultException fault)
                return fault;

            var faultDetails = new BizFaultDetails
            {
                Id = $"fault:{exception.GetId():N}",
                Time = DateTime.Now,
                Source = Source,
                ExceptionDetails = IncludeExceptionDetails ? exception.StackTrace : null
            };

            var normReason = GetReason(exception);
            
            return new FaultException<BizFaultDetails>(faultDetails, normReason);
        }

        private string GetReason(Exception exception)
        {
            var bizMessage = BizMessage.GetOrCreateForException(exception);

            var unnormalizedReason = bizMessage?.Content ??
                (HideInner
                    ? BizMessage.GetDefaultBizMessage()
                    : exception.Message);

            var normReason = NormStr(unnormalizedReason);
            return normReason;
        }

        string NormStr(string str)
        {
            if (str == null)
                return null;
            return str.Length <= StringLenLim
                ? str
                : str.Remove(StringLenLim);
        }
    }
}
