using ryCommon;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace ryCommon
{
    /// <summary>
    /// Hosts操作类
    /// </summary>
    public static class Hosts
    {
        /// <summary>
        /// 获取并转换hosts内容
        /// </summary>
        /// <param name="content">hosts内容</param>
        /// <returns></returns>
        public static List<HostInfo> GetHosts(string content)
        {
            var list = new List<HostInfo>();
            var from_list = content.Replace("\r", "").Replace("\t", " ").Split('\n');
            for (int i = 0; i < from_list.Length; i++)
            {
                var item = from_list[i].Trim();
                if (item.IndexOfEx("#") == 0) { list.Add(new HostInfo() { Comment=item }); continue; }
                int pos = item.IndexOfEx(" ");
                if (pos <= 0) {
                    if (item.StartsWith("!", StringComparison.OrdinalIgnoreCase))
                    {
                        list.Add(new HostInfo() { IP = "", Domain = item.Substring(1), IsDel = true });
                    }
                    continue; 
                }
                var ip = item.Substring(0, pos);//ip
                bool isDel = false;
                if(ip.StartsWith("!", StringComparison.OrdinalIgnoreCase))
                {
                    isDel = true;ip = ip.Substring(1);
                }
                var domain = item.Substring(pos + 1).Trim();//域名
                list.Add(new HostInfo() {IP=ip,Domain=domain,IsDel=isDel });
            }
            return list;
        }
        /// <summary>
        /// 获取hosts并转换hosts内容
        /// </summary>
        /// <returns></returns>
        public static List<HostInfo> GetHosts()
        {
            var hosts_path = ryCommon.RyFiles.GetRealPath("<sys>\\drivers\\etc\\hosts");
            var content = ryCommon.RyFiles.ReadAllText(hosts_path).Trim();
            return GetHosts(content);
        }
        /// <summary>
        /// 追加内容到hosts里
        /// </summary>
        /// <param name="list">要追加的内容列表，每一行为ip 域名的格式</param>
        /// <returns>0表示无需新增,-1表示添加失败,1表示追加成功</returns>
        public static int AddHosts(string list)
        {
            return AddHosts(list,true);
        }
        /// <summary>
        /// write为true,追加内容到hosts里;为false,判断是否需要追加
        /// </summary>
        /// <param name="list">要追加的内容列表，每一行为ip 域名的格式</param>
        /// <param name="write">是否要写入,如果为false,则只判断是否需要追加,而不写入Hosts文件</param>
        /// <returns>0表示无需新增,-1表示添加失败,1表示追加成功</returns>
        public static int AddHosts(string list,bool write)
        {
            var hosts_path= ryCommon.RyFiles.GetRealPath("<sys>\\drivers\\etc\\hosts");
            var content = ryCommon.RyFiles.ReadAllText(hosts_path).Trim();
            var from_list = GetHosts(content);
            var _list = GetHosts(list);
            bool isAdd = false;//是否有增加数据到hosts里
            for (int i = 0; i < _list.Count; i++)
            {
                bool HaveRecord = false;
                for (int m = from_list.Count-1; m>=0; m--) //去host文件里查找是否已含有该内容
                {
                    if (from_list[m].Comment.Length > 0) { continue; }
                    if(_list[i].Domain.ToLower()== from_list[m].Domain.ToLower())
                    {
                        if (_list[i].IP.Length == 0 && _list[i].IsDel)
                        {
                            from_list.RemoveAt(m);
                            HaveRecord = true;
                        }
                        else
                        {
                            if (_list[i].IP != from_list[m].IP) //如果同样域名对应的ip不一样,则删除该项,然后再插入新的ip
                            {
                                from_list.RemoveAt(m);
                                HaveRecord = false;
                            }
                            else
                            {
                                if (_list[i].IsDel) //如果ip和网址一致,并且标注为删除,则删除
                                {
                                    from_list.RemoveAt(m);
                                }
                                HaveRecord = true;
                            }
                        }
                    }
                }
                if(!HaveRecord)
                {
                    isAdd = true;
                    from_list.Add(_list[i]);
                }
            }
            if (isAdd)
            {
                if (write)
                {
                    try
                    {
                        content = "";
                        for (int i = 0; i < from_list.Count; i++)
                        {
                            if (content.Length > 0) { content += "\r\n"; }
                            if (from_list[i].Comment.Length > 0)
                            {
                                content += from_list[i].Comment;
                            }
                            else
                            {
                                content += from_list[i].IP + "\t" + from_list[i].Domain;
                            }
                        }
                        ryCommon.RyFiles.WriteAllText(hosts_path, content, Encoding.UTF8);
                    }
                    catch
                    {
                        return -1;
                    }
                }
            }
            else
            { return 0; }
            return 1;
        }
        /// <summary>
        /// 追加内容到hosts里
        /// </summary>
        /// <param name="item">要追加的内容</param>
        /// <returns>0表示无需新增,-1表示添加失败,1表示追加成功</returns>
        public static int AddHosts(HostInfo item)
        {
            return AddHosts(item.IP + "\t" + item.Domain);
        }
        /// <summary>
        /// 追加内容到hosts里
        /// </summary>
        /// <param name="ip">ip地址</param>
        /// <param name="domain">域名</param>
        /// <returns>0表示无需新增,-1表示添加失败,1表示追加成功</returns>
        public static int AddHosts(string ip,string domain)
        {
            return AddHosts(ip + "\t" + domain);
        }
        /// <summary>
        /// 从hosts文件里删除内容
        /// </summary>
        /// <param name="item">要删除的内容</param>
        /// <returns>0表示无需删除,-1表示添加失败,1表示删除成功</returns>
        public static int DelHosts(HostInfo item)
        {
            var hosts_path = ryCommon.RyFiles.GetRealPath("<sys>\\drivers\\etc\\hosts");
            var content = ryCommon.RyFiles.ReadAllText(hosts_path).Trim();
            var from_list = GetHosts(content);
            bool IsDel = false;
            for (int i = from_list.Count-1; i>=0; i++)
            {
                if(from_list[i].IP==item.IP && from_list[i].Domain.ToLower()==item.Domain.ToLower())
                {
                    from_list.RemoveAt(i);
                    IsDel = true;
                }
                else if (item.IP.Length==0 && from_list[i].Domain.ToLower() == item.Domain.ToLower())
                {
                    from_list.RemoveAt(i);
                    IsDel = true;
                }
            }
            var text = "";
            for (int i = 0; i < from_list.Count; i++)
            {
                if (text.Length > 0) { text += "\r\n"; }
                if(from_list[i].Comment.Length>0)
                {
                    text += from_list[i].Comment;
                }
                else
                {
                    text += from_list[i].IP+"\t"+ from_list[i].Domain;
                }
            }
            if (IsDel)
            {
                try
                {
                    ryCommon.RyFiles.WriteAllText(hosts_path, text, Encoding.UTF8);
                }
                catch
                {
                    return -1;
                }
            }
            else
            { return 0; }
            return 1;
        }
        /// <summary>
        /// 从hosts文件里删除内容
        /// </summary>
        /// <param name="ip">ip地址</param>
        /// <param name="domain">域名</param>
        /// <returns>0表示无需删除,-1表示添加失败,1表示删除成功</returns>
        public static int DelHosts(string ip, string domain)
        {
            return DelHosts(new HostInfo() {IP=ip,Domain=domain });
        }
    }
    /// <summary>
    /// Host信息
    /// </summary>
    public class HostInfo
    {
        /// <summary>
        /// IP
        /// </summary>
        public string IP { get; set; } = "";
        /// <summary>
        /// 域名
        /// </summary>
        public string Domain { get; set; } = "";
        /// <summary>
        /// 注释
        /// </summary>
        public string Comment { get; set; } = "";
        /// <summary>
        /// 是否要删除
        /// </summary>
        public bool IsDel { get; set; } = false;
    }
}
