using ESRI.ArcGIS.Controls;
using ESRI.ArcGIS.Geodatabase;
using ESRI.ArcGIS.Geometry;
using KGIS.Framework.AE.ExtensionMethod;
using KGIS.Framework.Core.Services;
using KGIS.Framework.Maps;
using KGIS.Framework.Utils;
using KGIS.Framework.Utils.ExtensionMethod;
using KGIS.Framework.Utils.Helper;
using Kingo.Core.Authorize;
using System;
using System.Configuration;
using System.IO;
using System.Text;
using System.Windows.Forms;
namespace Kingo.PluginServiceInterface.Helper
{
    //验证授权
    public static class AuthorizationVerification
    {
        #region 验证授权文件
        /// 
        /// 验证授权文件
        /// 
        /// 
        /// 是否修改
        /// 
        public static bool ValidityLic(object obj, bool isModify)
        {
            bool _Validity = true;
            try
            {
                //判断授权方式
                var type = ConfigurationManager.AppSettings.Get("LicenseType");
                string jkrjSQ = System.IO.Path.Combine(SysAppPath.GetCurrentAppPath(), "jkrj.lic");
                string SQTemp = System.IO.Path.Combine(SysAppPath.GetCurrentAppPath(), "SQTemp");
                if (type == "F")//本地授权
                {
                    if (File.Exists(jkrjSQ) && isModify)
                    {
                        if (Directory.Exists(SQTemp)) Directory.Delete(SQTemp, true);
                        Directory.CreateDirectory(SQTemp);
                        File.Copy(jkrjSQ, System.IO.Path.Combine(SQTemp, "jkrj.lic"), true);
                        File.Delete(jkrjSQ);
                    }
                    try
                    {
                        string[] licpath = System.IO.Directory.GetFiles(System.Environment.CurrentDirectory, "*.lic", System.IO.SearchOption.TopDirectoryOnly);
                        if (licpath.Length == 0)
                        {
                            MessageHelper.ShowError("授权校验失败!");
                        }
                        if (licpath.Length == 0 || !RunIDService2.Instance.Verify(AuthorizeType.多合一授权, "KGIS_SJJK", "500", "5x", "", "B0FEC8F"))
                        {
                            KGIS.PlatformPlugin.Views.License.LicenseView lic = new KGIS.PlatformPlugin.Views.License.LicenseView(obj, "KGIS_SJJK", "500", "5x");
                            lic.Code = "B0FEC8F";
                            DialogResult dialog = lic.ShowDialog();
                            if (dialog != DialogResult.Yes && dialog != DialogResult.OK)
                            {
                                _Validity = false;
                                if (isModify)
                                {
                                    File.Copy(System.IO.Path.Combine(SQTemp, "jkrj.lic"), jkrjSQ, true);
                                    Directory.Delete(SQTemp, true);
                                }
                                return _Validity;
                            }
                        }
                        else
                        {
                            _Validity = true;
                            return _Validity;
                        }
                    }
                    catch (Exception ex)
                    {
                        MessageHelper.Show(ex.Message);
                        KGIS.Framework.Utils.LogAPI.Debug(ex);
                        KGIS.PlatformPlugin.Views.License.LicenseView lic = new KGIS.PlatformPlugin.Views.License.LicenseView(obj, "KGIS_SJJK", "500", "5x");
                        lic.Code = "B0FEC8F";
                        DialogResult dialog = lic.ShowDialog();
                        if (dialog != DialogResult.Yes || dialog != DialogResult.OK)
                        {
                            _Validity = false;
                            if (isModify)
                            {
                                File.Copy(System.IO.Path.Combine(SQTemp, "jkrj.lic"), jkrjSQ, true);
                                Directory.Delete(SQTemp, true);
                            }
                            return _Validity;
                        }
                    }
                }
                else if (type == "D")
                {
                    //if (!RunIDService2.Instance.Verify("BGDCPRO", "300", "3x"))
                    //{
                    //    KGIS.PlatformPlugin.Views.License.LicenseView lic = new KGIS.PlatformPlugin.Views.License.LicenseView(obj, "KGIS_SJJK", "400", "4x");
                    //    DialogResult dialog = lic.ShowDialog();
                    //    if (dialog != DialogResult.Yes && dialog != DialogResult.OK)
                    //    {
                    //        _Validity = false;
                    //        return _Validity;
                    //    }
                    //}
                }
                else
                {
                    //KGIS.PlatformPlugin.Views.License.LicenseView lic = new KGIS.PlatformPlugin.Views.License.LicenseView(obj, "KGIS_SJJK", "400", "4x");
                    //int num = -1;
                    //lic.DocValidity = Validity;
                    //DialogResult dialog = lic.ShowDialog();
                    //if (dialog != DialogResult.Yes || dialog != DialogResult.OK)
                    //{
                    //    _Validity = false;
                    //    return _Validity;
                    //}
                }
            }
            catch (Exception ex)
            {
                LogAPI.Debug("授权验证异常:" + ex.Message + ex.StackTrace);
            }
            return _Validity;
        }
        /// 
        /// 验证授权文件多版本
        /// 
        /// 
        /// 是否修改
        /// 版本号
        /// 
        public static bool ValidityLic(object obj, bool isModify, int Version = 5)
        {
            bool _Validity = true;
            try
            {
                //判断授权方式
                var type = ConfigurationManager.AppSettings.Get("LicenseType");
                string jkrjSQ = System.IO.Path.Combine(SysAppPath.GetCurrentAppPath(), "jkrj.lic");
                string SQTemp = System.IO.Path.Combine(SysAppPath.GetCurrentAppPath(), "SQTemp");
                if (type == "F")//本地授权
                {
                    if (File.Exists(jkrjSQ) && isModify)
                    {
                        if (Directory.Exists(SQTemp)) Directory.Delete(SQTemp, true);
                        Directory.CreateDirectory(SQTemp);
                        File.Copy(jkrjSQ, System.IO.Path.Combine(SQTemp, "jkrj.lic"), true);
                        File.Delete(jkrjSQ);
                    }
                    try
                    {
                        string[] licpath = System.IO.Directory.GetFiles(System.Environment.CurrentDirectory, "*.lic", System.IO.SearchOption.TopDirectoryOnly);
                        if (licpath.Length == 0)
                        {
                            MessageHelper.ShowError("授权校验失败!");
                        }
                        if (licpath.Length == 0 || !RunIDService2.Instance.Verify(AuthorizeType.多合一授权, "KGIS_SJJK", $"{Version}00", $"{Version}x", "", "B0FEC8F"))
                        {
                            KGIS.PlatformPlugin.Views.License.LicenseView lic = new KGIS.PlatformPlugin.Views.License.LicenseView(obj, "KGIS_SJJK", $"{Version}00", $"{Version}x");
                            lic.Code = "B0FEC8F";
                            DialogResult dialog = lic.ShowDialog();
                            if (dialog != DialogResult.Yes && dialog != DialogResult.OK)
                            {
                                _Validity = false;
                                if (isModify)
                                {
                                    File.Copy(System.IO.Path.Combine(SQTemp, "jkrj.lic"), jkrjSQ, true);
                                    Directory.Delete(SQTemp, true);
                                }
                                return _Validity;
                            }
                        }
                        else
                        {
                            _Validity = true;
                            return _Validity;
                        }
                    }
                    catch (Exception ex)
                    {
                        MessageHelper.Show(ex.Message);
                        KGIS.Framework.Utils.LogAPI.Debug(ex);
                        KGIS.PlatformPlugin.Views.License.LicenseView lic = new KGIS.PlatformPlugin.Views.License.LicenseView(obj, "KGIS_SJJK", $"{Version}00", $"{Version}x");
                        lic.Code = "B0FEC8F";
                        DialogResult dialog = lic.ShowDialog();
                        if (dialog != DialogResult.Yes || dialog != DialogResult.OK)
                        {
                            _Validity = false;
                            if (isModify)
                            {
                                File.Copy(System.IO.Path.Combine(SQTemp, "jkrj.lic"), jkrjSQ, true);
                                Directory.Delete(SQTemp, true);
                            }
                            return _Validity;
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                LogAPI.Debug("授权验证异常:" + ex.Message + ex.StackTrace);
            }
            return _Validity;
        }
        #endregion
        #region 绘制授权范围
        /// 
        /// 绘制授权范围
        /// 
        /// 
        /// 
        public static IGeometry DrawAuthorizationRange(ISpatialReference spatialReference)
        {
            IGeometry geo = null;
            try
            {
                //授权区域为空
                if (string.IsNullOrWhiteSpace(RunIDService2.Instance.Area))
                    return null;
                string ring = SysConfigsOprator.GetAppsetingValueByKey("Ring");
                ring = Decrypt(ring, RunIDService2.Instance.Secretkey);
                IPointCollection py = new PolygonClass();
                ring = ring.Replace("POLYGON((", "").Replace("))", "");
                string[] points = ring.Split(',');
                foreach (var item in points)
                {
                    string[] xy = item.Split(' ');
                    if (!string.IsNullOrEmpty(xy[0]))
                        py.AddPoint(new PointClass() { X = xy[0].ToDouble(), Y = xy[1].ToDouble() });
                }
                geo = py as IPolygon;
                ISpatialReferenceFactory NewSpatialReference = new SpatialReferenceEnvironmentClass();
                geo.SpatialReference = NewSpatialReference.CreateProjectedCoordinateSystem(4530); //NewSpatialReference.CreateGeographicCoordinateSystem(4490); 
                geo.Project(spatialReference);
                ITopologicalOperator topo = geo as ITopologicalOperator;
                //geo = topo.Buffer(2000);
                //geo = geo.Envelope;
                //IPointCollection ps2 = geo as IPointCollection;
                //IPointCollection py2 = new PolygonClass();
                //py2.AddPoint(new PointClass() { X = geo.Envelope.XMax, Y = geo.Envelope.YMax });
                //py2.AddPoint(new PointClass() { X = geo.Envelope.XMax, Y = geo.Envelope.YMin });
                //py2.AddPoint(new PointClass() { X = geo.Envelope.XMin, Y = geo.Envelope.YMin });
                //py2.AddPoint(new PointClass() { X = geo.Envelope.XMin, Y = geo.Envelope.YMax });
                //py2.AddPoint(new PointClass() { X = geo.Envelope.XMax, Y = geo.Envelope.YMax });
                //IGeometry geo22 = py2 as IPolygon;
                //geo22.SpatialReference = spatialReference;
                //geo22.Project(NewSpatialReference.CreateGeographicCoordinateSystem(4490));
                //py2 = geo22 as IPointCollection;
                //string strPly = "POLYGON((";
                //for (int i = 0; i < py2.PointCount; i++)
                //{
                //    strPly += py2.Point[i].X + " " + py2.Point[i].Y + ",";
                //}
                //strPly += "))";
                //byte[] bt=(MapsManager.Instance.MapService.GetProjectInfo() as ProjectInfo).AesEncrypt(strPly, RunIDService2.Instance.Secretkey);
                //strPly = Convert.ToBase64String(bt);
                string SQstring = RunIDService2.Instance.Area.Replace('\r', ' ').ToTrim();
                string[] rings = SQstring.Split(new char[] { '|' }, StringSplitOptions.RemoveEmptyEntries);
                string coord = string.Empty;
                if (rings.Length > 550) return null;
                if (rings.Length > 0)
                {
                    coord = "MULTIPOLYGON(";
                    foreach (var r in rings)
                    {
                        string Temp_Coordinate = string.Empty;
                        string[] ps = r.TrimEnd(';').Split(';');
                        string strRing = "((";
                        if (ps.Length == 1)
                        {
                            strRing += ps[0];
                        }
                        else
                        {
                            foreach (var item in ps)
                            {
                                strRing += item.Replace('\n', ' ').Replace(',', ' ') + ",";
                            }
                        }
                        char[] charsToTrim = { ',' };
                        strRing = strRing.TrimEnd(charsToTrim);
                        strRing = strRing.ToTrim();
                        strRing = strRing.TrimEnd(charsToTrim);
                        strRing += ")),";
                        coord += strRing;
                    }
                    coord = coord.TrimEnd(',');
                    coord += ")";
                    IGeometry geo2 = AECommonHelper.GetPolygonFromWkt(coord);
                    if (geo2 == null) return geo;
                    geo2.SpatialReference = NewSpatialReference.CreateGeographicCoordinateSystem(4490);
                    geo2.Project(spatialReference);
                    IGeometryCollection ExterRingGeometryCollection = geo2 as IGeometryCollection;
                    if (ExterRingGeometryCollection == null) return geo;
                    IGeometryCollection geometry = new ESRI.ArcGIS.Geometry.PolygonClass() as IGeometryCollection;
                    for (int i = 0; i < ExterRingGeometryCollection.GeometryCount; i++)
                    {
                        IGeometry ExterGeometry = ExterRingGeometryCollection.get_Geometry(i);
                        double geoArea = ((IArea)ExterGeometry).Area;
                        if (geoArea < 0.1)
                        {
                            continue;
                        }
                        if (ExterGeometry != null && !ExterGeometry.IsEmpty)
                        {
                            geometry.AddGeometry(ExterGeometry);
                        }
                        else
                        {
                            continue;
                        }
                    }
                    ITopologicalOperator topo2 = geometry as ITopologicalOperator;
                    IGeometry buf = topo2.Buffer(2000);
                    GeometryBag ExterGeometryBag = (buf as ESRI.ArcGIS.Geometry.IPolygon4).ExteriorRingBag as GeometryBag;
                    ExterRingGeometryCollection = ExterGeometryBag as IGeometryCollection;
                    geometry = new ESRI.ArcGIS.Geometry.PolygonClass() as IGeometryCollection;
                    for (int i = 0; i < ExterRingGeometryCollection.GeometryCount; i++)
                    {
                        IGeometry ExterGeometry = ExterRingGeometryCollection.get_Geometry(i);
                        if (ExterGeometry != null && !ExterGeometry.IsEmpty)
                        {
                            geometry.AddGeometry(ExterGeometry);
                        }
                        else
                        {
                            continue;
                        }
                    }
                    topo = geo as ITopologicalOperator;
                    geo = topo.Difference(geometry as IGeometry);
                }
                else
                {
                    foreach (var geoRing in rings)
                    {
                        string strGeo = geoRing.Replace('\r', ' ').ToTrim();
                        if (strGeo.Split(new char[] { ';' }).Length < 10)
                            strGeo = geoRing.Replace(";", ",");
                        if (strGeo.Contains(";"))
                        {
                            coord = string.Format("POLYGON((");
                            string[] ps = strGeo.TrimEnd(';').Split(';');
                            foreach (var item in ps)
                            {
                                coord += item.Replace('\r', ' ').Replace(',', ' ') + ",";
                            }
                        }
                        else
                        {
                            coord = string.Format("POLYGON((");
                            coord += strGeo;
                        }
                        coord = coord.TrimEnd(',');
                        coord += "))";
                        IGeometry geo2 = AECommonHelper.GetPolygonFromWkt(coord);
                        if (geo2 == null) return geo;
                        IArea area = geo2 as IArea;
                        if (area.Area < 0)
                        {
                            (geo2 as IPolygon).ReverseOrientation();
                        }
                        geo2.SpatialReference = NewSpatialReference.CreateGeographicCoordinateSystem(4490);
                        geo2.Project(spatialReference);
                        ITopologicalOperator topo2 = geo2 as ITopologicalOperator;
                        IGeometry buf = topo2.Buffer(2000);
                        topo = geo as ITopologicalOperator;
                        GeometryBag ExterGeometryBag = (buf as ESRI.ArcGIS.Geometry.IPolygon4).ExteriorRingBag as GeometryBag;
                        if (ExterGeometryBag == null) continue;
                        IGeometryCollection ExterRingGeometryCollection = ExterGeometryBag as IGeometryCollection;
                        IGeometryCollection geometry = new ESRI.ArcGIS.Geometry.PolygonClass() as IGeometryCollection;
                        for (int i = 0; i < ExterRingGeometryCollection.GeometryCount; i++)
                        {
                            IGeometry ExterGeometry = ExterRingGeometryCollection.get_Geometry(i);
                            if (ExterGeometry != null && !ExterGeometry.IsEmpty)
                            {
                                geometry.AddGeometry(ExterGeometry);
                            }
                            else
                            {
                                continue;
                            }
                        }
                        geo = topo.Difference(geometry as IGeometry);
                    }
                }
            }
            catch (Exception ex)
            {
                LogAPI.Debug("绘制授权范围异常:" + ex.Message + ex.StackTrace);
            }
            return geo;
        }
        #endregion
        #region Decrypt
        /// 
        /// 解密
        /// 
        /// 
        /// 
        /// 
        /// 
        public static string Decrypt(string content, string strKey)
        {
            string result = string.Empty;
            try
            {
                if (string.IsNullOrWhiteSpace(content))
                    return string.Empty;
                System.Security.Cryptography.RijndaelManaged rm = new System.Security.Cryptography.RijndaelManaged
                {
                    Key = Encoding.UTF8.GetBytes(strKey),
                    Mode = System.Security.Cryptography.CipherMode.ECB,
                    Padding = System.Security.Cryptography.PaddingMode.PKCS7
                };
                //将base64字符串转换成byte数组
                byte[] contentArray = Convert.FromBase64String(content);
                //创建解密转换器
                System.Security.Cryptography.ICryptoTransform cDecryptTransform = rm.CreateDecryptor();
                //对byte数组进行解密转换
                Byte[] DecryptArray = cDecryptTransform.TransformFinalBlock(contentArray, 0, contentArray.Length);
                //将解密后的byte[]转换成字符串(base64)
                string strDecrypt = Encoding.UTF8.GetString(DecryptArray);
                //将base64字符串转换成8位无符号整数数组
                byte[] base64ToByte = Convert.FromBase64String(strDecrypt);
                //string s = Encoding.UTF8.GetString(base64ToByte);
                //将8位无符号整数数组转换成等效字符串,并返回
                return Encoding.UTF8.GetString(base64ToByte);
            }
            catch (Exception ex)
            {
                throw new Exception("解密工程文件异常:" + ex.Message);
            }
            finally
            {
                GC.Collect();
            }
        }
        #endregion
        #region 验证授权范围
        /// 
        /// 验证授权范围
        /// 
        /// 
        /// 
        public static bool VerifyRange(IFeatureClass FeatureClass)
        {
            bool VerifyMandate = false;
            try
            {
                if ((FeatureClass as FeatureClass).Workspace.Type != esriWorkspaceType.esriRemoteDatabaseWorkspace)
                {
                    IFeatureClassManage fcManage = FeatureClass as IFeatureClassManage;
                    fcManage.UpdateExtent();
                }
                IEnvelope envelope = (FeatureClass as IGeoDataset).Extent;
                if (string.IsNullOrWhiteSpace(RunIDService2.Instance.Area) || envelope.IsEmpty)
                {
#if DEBUG
                    return true;
#else
                    LogAPI.Debug("未能获取有效的授权信息,数据导出失败!");
                    return VerifyMandate;
#endif
                }
                if (!string.IsNullOrWhiteSpace(RunIDService2.Instance.Area))
                {
                    IGeometry geo = AECommonHelper.GetPolygonFromWkt(RunIDService2.Instance.Area);
                    IArea area = geo as IArea;
                    if (area.Area < 0)
                    {
                        (geo as IPolygon).ReverseOrientation();
                    }
                    ISpatialReferenceFactory NewSpatialReference = new SpatialReferenceEnvironmentClass();
                    geo.SpatialReference = NewSpatialReference.CreateGeographicCoordinateSystem(4490);
                    geo.Project(MapsManager.Instance.MapService.getAxMapControl().SpatialReference);
                    IPointCollection poly = new PolygonClass();
                    poly.AddPoint(new PointClass() { X = envelope.XMin, Y = envelope.YMax });
                    poly.AddPoint(new PointClass() { X = envelope.XMax, Y = envelope.YMax });
                    poly.AddPoint(new PointClass() { X = envelope.XMax, Y = envelope.YMin });
                    poly.AddPoint(new PointClass() { X = envelope.XMin, Y = envelope.YMin });
                    poly.AddPoint(new PointClass() { X = envelope.XMin, Y = envelope.YMax });
                    IGeometry geo2 = poly as IGeometry;
                    IPointCollection poly2 = new PolygonClass();
                    poly2.AddPoint(new PointClass() { X = geo.Envelope.XMin, Y = geo.Envelope.YMax });
                    poly2.AddPoint(new PointClass() { X = geo.Envelope.XMax, Y = geo.Envelope.YMax });
                    poly2.AddPoint(new PointClass() { X = geo.Envelope.XMax, Y = geo.Envelope.YMin });
                    poly2.AddPoint(new PointClass() { X = geo.Envelope.XMin, Y = geo.Envelope.YMin });
                    poly2.AddPoint(new PointClass() { X = geo.Envelope.XMin, Y = geo.Envelope.YMax });
                    geo = poly2 as IGeometry;
                    geo.SpatialReference = MapsManager.Instance.MapService.getAxMapControl().SpatialReference;
                    geo2.SpatialReference = MapsManager.Instance.MapService.getAxMapControl().SpatialReference;
                    ITopologicalOperator topo = geo as ITopologicalOperator;
                    IGeometry newGeo = topo.Intersect(geo2, geo2.Dimension);
                    double d = geo.GetEllipseArea();
                    double d1 = geo2.GetEllipseArea();
                    double newD = newGeo.GetEllipseArea();
                    if (newD / d1 < 0.8)
                        return VerifyMandate;
                    else
                        VerifyMandate = true;
                }
            }
            catch (Exception ex)
            {
                LogAPI.Debug("验证授权范围异常:" + ex.Message + ex.StackTrace);
                VerifyMandate = false;
            }
            return VerifyMandate;
        }
        #endregion
    }
}