using System;
using System.Collections.Generic;
using System.Text;

namespace Apewer.Internals
{

    internal class TextModifier
    {

        /// <summary>为字符串前添加字符“0”。</summary>
        /// <param name="argValue">原字符串,内容应为整数、小数或十六进制数,若格式不符则返回原字符串。</param>
        /// <param name="argLength">新字符串的长度,若大于原数字长度,则不添加额外的“0”。</param>
        public static string PreZero(string argValue, int argLength = 0)
        {
            string vresult = string.IsNullOrEmpty(argValue) ? "" : Trim(argValue);
            if (TextVerifier.IsNumber(vresult))
            {
                if (vresult.Substring(0, 1) == ".")
                {
                    vresult = "0" + vresult;
                }
                var vcc = TextGenerator.CopyChar("0", argLength - TextHelper.Len(vresult));
                vresult = vcc + vresult;
            }
            return vresult;
        }

        /// <summary>删除字符串前额外的字符“0”。</summary>
        public static string RemoveZero(string argValue)
        {
            try
            {
                string vr = Trim(argValue);
                while ((TextHelper.Left(vr, 1) == "0") && (TextHelper.Len(vr) > 1))
                {
                    vr = TextHelper.Right(vr, TextHelper.Len(vr) - 1);
                }
                if (TextHelper.Left(vr, 1) == ".") vr = "0" + vr;
                return vr;
            }
            catch { return argValue; }
        }

        /// <summary>从父字符串中删除子字符串。</summary>
        /// <param name="argParent">父字符串。</param>
        /// <param name="argSub">子字符串。</param>
        /// <param name="argIgnoreCase">是否忽略大小写。</param>
        /// <returns>删除子字符串后的父字符串。</returns>
        public static string Exlude(string argParent, string argSub, bool argIgnoreCase = false)
        {
            if (string.IsNullOrEmpty(argParent)) return "";
            if (string.IsNullOrEmpty(argSub)) return argParent;
            try
            {
                string vp = argParent;
                string vs = argSub;
                string vr = "";
                int vl;
                int vi;
                if (argIgnoreCase)
                {
                    vp = TextHelper.LCase(vp);
                    vs = TextHelper.LCase(vs);
                }
                vl = vs.Length;
                vi = 1;
                while (vi <= (vp.Length - vl + 1))
                {
                    if (TextHelper.Middle(vp, vi, vl) == vs)
                    {
                        vi = vi + vl;
                    }
                    else
                    {
                        vr = vr + TextHelper.Middle(argParent, vi, 1);
                        vi = vi + 1;
                    }

                }
                return vr;
            }
            catch { return argParent; }
        }

        /// <summary>替换父字符串中的子字符串。</summary>
        /// <param name="argParent">父字符串。</param>
        /// <param name="argNew">新子字符串,保留大小写。</param>
        /// <param name="argOld">原子字符串。</param>
        /// <param name="argIgnoreCase">查找时是否忽略父字符串和原子字符串大小写。</param>
        /// <returns>替换后的父字符串。</returns>
        public static string Replace(string argParent, string argOld, string argNew, bool argIgnoreCase = false)
        {
            if (string.IsNullOrEmpty(argParent)) return "";
            if (string.IsNullOrEmpty(argOld)) return argParent;
            if (string.IsNullOrEmpty(argNew)) return Exlude(argParent, argOld, argIgnoreCase);
            if (TextHelper.Len(argParent) < TextHelper.Len(argOld)) return argParent;
            if (argIgnoreCase)
            {
                try
                {
                    string vparent = TextHelper.LCase(argParent);
                    string vold = TextHelper.LCase(argOld);
                    int vil = TextHelper.Len(argOld);
                    int viv = 1;
                    int vend = TextHelper.Len(argParent) - vil + 1;
                    string vcell;
                    string vresult = "";
                    while (viv <= vend)
                    {
                        vcell = TextHelper.Middle(vparent, viv, vil);
                        if (vcell == vold)
                        {
                            vresult = vresult + argNew;
                            viv = viv + vil;
                        }
                        else
                        {
                            vresult = vresult + TextHelper.Middle(argParent, viv, 1);
                            viv = viv + 1;
                        }
                    }
                    return vresult;
                }
                catch { return argParent; }
            }
            else
            {
                try
                {
                    string vresult = argParent.Replace(argOld, argNew);
                    return vresult;
                }
                catch { return ""; }
            }
        }

        public static string AssureEnds(string argOrigin, bool argInclude = true, string argFoot = "\\")
        {
            if (string.IsNullOrEmpty(argOrigin)) return "";
            if (string.IsNullOrEmpty(argFoot)) return "";

            var text = argOrigin;
            var len = argFoot.Length;
            var last = text.Substring(text.Length - len, len);
            if (argInclude == true)
            {
                if (last != argFoot) text += argFoot;
            }
            else
            {
                while (last == argFoot)
                {
                    text = text.Substring(0, text.Length - len);
                    last = (text.Length > len) ? text.Substring(text.Length - len, len) : "";
                }
            }

            return text;
        }

        public static string Trim(string argOrigin, bool argIncludeSbcCase = false)
        {
            if (argOrigin == null) return Constant.EmptyString;
            if (argOrigin.Length < 1) return Constant.EmptyString;

            var result = argOrigin.Trim();
            if (!argIncludeSbcCase) return result;

            const string sbc = " ";
            while (true)
            {
                if (result.Length < 1) break;
                if (result.Equals(sbc))
                {
                    result = Constant.EmptyString;
                    break;
                }

                var left = result.Substring(0, 1);
                if (left.Equals(sbc))
                {
                    result = result.Substring(1, result.Length - 1);
                    continue;
                }

                var right = result.Substring(result.Length - 1, 1);
                if (right.Equals(sbc))
                {
                    result = result.Substring(0, result.Length - 1);
                    continue;
                }

                break;
            }
            return result;

            //if (argIncludeSbcCase)
            //{

            //}

            //if (string.IsNullOrEmpty(argOrigin)) return "";

            //var result = null as string;
            //try
            //{
            //    result = argOrigin.Trim();
            //    if (!argIncludeSbcCase) return result;
            //}
            //catch { }

            //try
            //{
            //    if (string.IsNullOrEmpty(result)) return "";

            //    // 前缀长度。
            //    int left = 0;
            //    for (int i = 0; i < result.Length; i++)
            //    {
            //        if (TextVerifier.IsBlank(result[i], argIncludeSbcCase)) left += 1;
            //        else break;
            //    }
            //    if (left >= result.Length) return "";

            //    // 后缀长度。
            //    int right = 0;
            //    for (int i = result.Length - 1; i >= left; i--)
            //    {
            //        if (TextVerifier.IsBlank(result[i], argIncludeSbcCase)) right += 1;
            //        else break;
            //    }

            //    // 检查长度。
            //    if (left + right <= result.Length) result = Constant.EmptyString;
            //    return TextHelper.Middle(result, left, result.Length - left - right);
            //}
            //catch { }

            //return argOrigin ?? Constant.EmptyString;
        }

        /// <summary>防注入处理,去除会引发代码注入的字符,控制字符串长度(去除超出部分)。</summary>
        public static string AntiInject(string text, int length, IEnumerable<char> blacklist)
        {
            if (string.IsNullOrEmpty(text)) return Constant.EmptyString;
            if (length == 0) return Constant.EmptyString;

            // Trim。
            var output = text.Trim();
            if (output.Length < 1) return Constant.EmptyString;

            // 替换。
            if (blacklist != null)
            {
                foreach (var i in blacklist) output.Replace(i.ToString(), "");
            }

            // 限制长度。
            if (length > 0 && output.Length > length) output = output.Substring(0, length);

            return output;
        }

        /// <summary>剪取文本内容,若指定头部为空则从原文本首部起,若指定尾部为空则至原文本末尾。</summary>
        public static string Cut(string argOrigin, string argHead = null, string argFoot = null)
        {
            if (string.IsNullOrEmpty(argOrigin)) return "";

            if ((string.IsNullOrEmpty(argHead)) && (!string.IsNullOrEmpty(argFoot)))
            {
                var vfoot = argOrigin.IndexOf(argFoot);
                if (vfoot < 0) return argOrigin;
                var vmiddle = argOrigin.Substring(0, vfoot);
                return vmiddle;
            }

            if ((!string.IsNullOrEmpty(argHead)) && (string.IsNullOrEmpty(argFoot)))
            {
                var vhead = argOrigin.IndexOf(argHead) + argHead.Length;
                if (vhead < 0) return argOrigin;
                var vmiddle = argOrigin.Substring(vhead, argOrigin.Length - vhead);
                return vmiddle;
            }

            {
                var ihead = argOrigin.IndexOf(argHead) + argHead.Length;
                if (ihead < 0) return "";

                var temp = argOrigin.Substring(ihead);
                var ifoot = temp.IndexOf(argFoot);
                if (ifoot < 0) return "";

                var result = temp.Substring(0, ifoot);
                return result;
            }
        }

        /// <summary>限制文本长度,并去除两边的空白字符。</summary>
        public static string Compact(string argInput, int argLength = 0)
        {
            var text = argInput ?? "";
            if (text.Length > 0) text = text.Trim();
            if (argLength > 0 && text.Length > argLength)
            {
                text = text.Substring(0, argLength);
                text = text.Trim();
            }
            return text;
        }

        public static List<string> Distinct(IEnumerable<string> argOrigin, bool argValid = false)
        {
            var list = new List<string>();
            if (argOrigin != null)
            {
                foreach (var item in argOrigin)
                {
                    var text = item;
                    if (text == null) continue;
                    if (argValid)
                    {
                        if (argValid && text != "") text = text.Trim();
                        if (TextVerifier.IsBlank(text)) continue;
                    }
                    if (list.Contains(text)) continue;
                    list.Add(text);
                }
            }
            return list;
        }

        /// <summary>约束字符串长度范围,超出的部分将被截取去除。</summary>
        public static string RestrictLength(string argOrigin, int argMaxLength)
        {
            if (argMaxLength <= 0) return Constant.EmptyString;
            var trim = Trim(argOrigin);
            if (trim.Length > argMaxLength) trim = trim.Substring(0, argMaxLength);
            return trim;
        }

        /// <summary>约束字符串中的字符,不允许的字符将被去除。</summary>
        public static string RestrictCharacters(string argOrigin, string argAllowableCharacters)
        {
            if (argOrigin == null || argOrigin.Length < 1) return "";
            if (argAllowableCharacters == null || argAllowableCharacters.Length < 1) return "";

            var sb = new StringBuilder();
            for (var i = 0; i < argOrigin.Length; i++)
            {
                var character = argOrigin[i];
                if (argAllowableCharacters.IndexOf(character) > -1) sb.Append(character);
            }
            var result = sb.ToString();
#if !NET20
            sb.Clear();
#endif
            return result;
        }

        /// <summary>约束字符串,只保留 GUID 可能出现的字符,根据连字符限定长度为 32 或 36,结果中字母将转换为小写。</summary>
        public static string RestrictGuid(string argOrigin)
        {
            if (TextVerifier.IsBlank(argOrigin)) return Constant.EmptyString;
            var origin = argOrigin.ToLower();

            var maxlength = (origin.IndexOf('-') > -1) ? 36 : 32;
            var result = RestrictCharacters(origin, Constant.GuidCollection);
            if (result.Length > maxlength) result = result.Substring(0, maxlength);

            return result;
        }

    }

}