using System;
using System.Collections.Generic;
using System.Text;
using NMaven.ProjectImporter.SlnParser;
using NMaven.ProjectImporter.SlnParser.Model;
using System.IO;
using NMaven.ProjectImporter.Parser.VisualStudioProjectTypes;
using System.Text.RegularExpressions;
using Microsoft.Build.BuildEngine;
using System.Xml;

/// Author: Leopoldo Lee Agdeppa III

namespace NMaven.ProjectImporter.Parser.Solution
{
    public class ProjectSolutionParser
    {

        protected static string PROJECT_REFERENCE_REGEX;

        protected static Engine BUILD_ENGINE;

        static ProjectSolutionParser()
        {
            PROJECT_REFERENCE_REGEX = @"({(?<ProjectReferenceGUID>([^\}])*)}\|(?<ProjectReferenceDll>([^;])*);)";

            // gets the directory path of mscorlib using the System.String Type Assembly path
            string msBuildPath = Path.GetDirectoryName(System.Reflection.Assembly.GetAssembly(typeof(string)).Location);
            BUILD_ENGINE = new Engine(msBuildPath);
        }


        public List<Dictionary<string, object>> Parse(FileInfo solutionFile)
        {

            List<Dictionary<string, object>> list = new List<Dictionary<string, object>>();
            NMaven.ProjectImporter.SlnParser.Model.Solution solution = SolutionFactory.GetSolution(solutionFile);


            foreach (NMaven.ProjectImporter.SlnParser.Model.Project project in solution.Projects)
            {
                Dictionary<string, object> dictionary = new Dictionary<string, object>();


                dictionary.Add("ProjectTypeGuid", project.ProjectTypeGUID);
                dictionary.Add("ProjectType", VisualStudioProjectType.GetVisualStudioProjectType(project.ProjectTypeGUID));

                dictionary.Add("ProjectName", project.ProjectName);
                dictionary.Add("ProjectPath", project.ProjectPath);
                dictionary.Add("ProjectGUID", project.ProjectGUID);

                string fullpath = Path.Combine(solutionFile.DirectoryName, project.ProjectPath);
                dictionary.Add("ProjectFullPath", fullpath);






                // this is for web projects
                if ((VisualStudioProjectTypeEnum)dictionary["ProjectType"] == VisualStudioProjectTypeEnum.Web_Site)
                {

                    string[] assemblies = GetWebConfigAssemblies(Path.Combine(fullpath, "web.config"));
                    dictionary.Add("WebConfigAssemblies", assemblies);


                    //@001 SERNACIO START retrieving webreference
                    Digest.Model.WebReferenceUrl[] webReferences = getWebReferenceUrls(fullpath);
                    dictionary.Add("WebReferencesUrl", webReferences);
                    //@001 SERNACIO END retrieving webreference

                    string[] binAssemblies = GetBinAssemblies(Path.Combine(fullpath, @"bin"));
                    dictionary.Add("BinAssemblies", binAssemblies);
                    //ParseInnerData(dictionary, match.Groups["projectInnerData"].ToString());
                    ParseProjectReferences(dictionary, project, solution);
                }
                // this is for normal projects
                else if (
                    (VisualStudioProjectTypeEnum)dictionary["ProjectType"] == VisualStudioProjectTypeEnum.Windows__CSharp
                    || (VisualStudioProjectTypeEnum)dictionary["ProjectType"] == VisualStudioProjectTypeEnum.Windows__VbDotNet
                    )
                {
                    Microsoft.Build.BuildEngine.Project prj = new Microsoft.Build.BuildEngine.Project(BUILD_ENGINE);
                    prj.Load(fullpath);
                    //ParseInnerData(dictionary, match.Groups["projectInnerData"].ToString());
                    ParseProjectReferences(dictionary, project, solution);
                    dictionary.Add("Project", prj);
                }

                list.Add(dictionary);


            }

            return list;
        }



        protected void ParseProjectReferences(Dictionary<string, object> dictionary, NMaven.ProjectImporter.SlnParser.Model.Project project, NMaven.ProjectImporter.SlnParser.Model.Solution solution)
        {
            if (project.ProjectSections != null)
            {
                List<Microsoft.Build.BuildEngine.Project> projectReferenceList = new List<Microsoft.Build.BuildEngine.Project>();
                foreach (ProjectSection ps in project.ProjectSections)
                {
                    if ("WebsiteProperties".Equals(ps.Name))
                    {
                        // ProjectReferences = "{11F2FCC8-5941-418A-A0E7-42D250BA9D21}|SampleInterProject111.dll;{9F37BA7B-06F9-4B05-925D-B5BC16322E8B}|BongClassLib.dll;"

                        try
                        {
                            Regex regex = new Regex(PROJECT_REFERENCE_REGEX, RegexOptions.Multiline | RegexOptions.IgnoreCase);
                            MatchCollection matches = regex.Matches(ps.Map["ProjectReferences"]);


                            foreach (Match match in matches)
                            {
                                string projectReferenceGUID = match.Groups["ProjectReferenceGUID"].ToString();
                                string projectReferenceDll = match.Groups["ProjectReferenceDll"].ToString();
                                
                                Microsoft.Build.BuildEngine.Project prj = GetMSBuildProject(solution, projectReferenceGUID);
                                if (prj != null)
                                {
                                    projectReferenceList.Add(prj);
                                }
                            }
                        }
                        catch { }




                    }
                    else if("ProjectDependencies".Equals(ps.Name))
                    {
                        //{0D80BE11-F1CE-409E-B9AC-039D3801209F} = {0D80BE11-F1CE-409E-B9AC-039D3801209F}

                        foreach (string key in ps.Map.Keys)
                        {
                            Microsoft.Build.BuildEngine.Project prj = GetMSBuildProject(solution, key.Replace("{","").Replace("}", ""));
                            if (prj != null)
                            {
                                projectReferenceList.Add(prj);
                            }
                        }

                    }
                }

                dictionary.Add("InterProjectReferences", projectReferenceList.ToArray());
            }


            
        }

        Microsoft.Build.BuildEngine.Project GetMSBuildProject(NMaven.ProjectImporter.SlnParser.Model.Solution solution, string projectGuid)
        {

            foreach (NMaven.ProjectImporter.SlnParser.Model.Project p in solution.Projects)
            {
                if (p.ProjectGUID.Equals("{" + projectGuid + "}", StringComparison.OrdinalIgnoreCase))
                {
                    string projectReferenceName = p.ProjectName;
                    string projectReferencePath = p.ProjectPath;
                    string projectReferenceFullPath = null;

                    if (Path.IsPathRooted(projectReferencePath))
                    {
                        projectReferenceFullPath = Path.GetFullPath(projectReferencePath);
                    }
                    else
                    {
                        projectReferenceFullPath = Path.Combine(solution.File.Directory.FullName, projectReferencePath);
                    }


                    Microsoft.Build.BuildEngine.Project prj = new Microsoft.Build.BuildEngine.Project(BUILD_ENGINE);
                    prj.Load(projectReferenceFullPath);

                    return prj;

                }
            }

            return null;
        }



        protected string[] GetWebConfigAssemblies(string webconfig)
        {
            List<string> list = new List<string>();

            string xpath_expr = @"//configuration/system.web/compilation/assemblies/add";

            FileInfo webConfigFile = new FileInfo(webconfig);

            if (!webConfigFile.Exists)
            {
                // return empty string array
                return list.ToArray();
            }


            XmlDocument xmldoc = new System.Xml.XmlDocument();
            xmldoc.Load(webConfigFile.FullName);

            XmlNodeList valueList = xmldoc.SelectNodes(xpath_expr);

            foreach (System.Xml.XmlNode val in valueList)
            {
                string assembly = val.Attributes["assembly"].Value;

                if (!string.IsNullOrEmpty(assembly))
                {
                    list.Add(assembly);
                }

            }



            return list.ToArray();

        }


        protected String[] GetBinAssemblies(string webBinDir)
        {
            List<string> list = new List<string>();

            DirectoryInfo dir = new DirectoryInfo(webBinDir);

            if (!dir.Exists)
            {
                // return an empty array string
                return list.ToArray();
            }

            foreach (FileInfo dll in dir.GetFiles("*.dll"))
            {
                list.Add(dll.FullName);

            }



            return list.ToArray();



        }



        Digest.Model.WebReferenceUrl[] getWebReferenceUrls(string projectPath)
        {
            List<Digest.Model.WebReferenceUrl> returnList = new List<Digest.Model.WebReferenceUrl>();
            string webPath = Path.GetFullPath(Path.Combine(projectPath, "App_WebReferences"));
            if (Directory.Exists(webPath))
            {
                DirectoryInfo dirInfo = new DirectoryInfo(webPath);
                foreach (DirectoryInfo folders in dirInfo.GetDirectories())
                {
                    if (folders.Equals(".svn")) continue;
                    returnList.AddRange(getWebReferenceUrls(folders, "App_WebReferences"));
                }
            }
            return returnList.ToArray();
        }

        Digest.Model.WebReferenceUrl[] getWebReferenceUrls(DirectoryInfo folder, string currentPath)
        {
            string relPath = Path.Combine(currentPath, folder.Name);
            string url = string.Empty;
            List<Digest.Model.WebReferenceUrl> webReferenceUrls = new List<Digest.Model.WebReferenceUrl>();

            FileInfo[] fileInfo = folder.GetFiles("*.discomap");
            if (fileInfo != null && fileInfo.Length > 0)
            {
                System.Xml.XPath.XPathDocument xDoc = new System.Xml.XPath.XPathDocument(fileInfo[0].FullName);
                System.Xml.XPath.XPathNavigator xNav = xDoc.CreateNavigator();
                string xpathExpression = @"DiscoveryClientResultsFile/Results/DiscoveryClientResult[@referenceType='System.Web.Services.Discovery.ContractReference']/@url";
                System.Xml.XPath.XPathNodeIterator xIter = xNav.Select(xpathExpression);
                if (xIter.MoveNext())
                {
                    url = xIter.Current.TypedValue.ToString();
                }
            }
            if (!string.IsNullOrEmpty(url))
            {
                Digest.Model.WebReferenceUrl newWebReferenceUrl = new Digest.Model.WebReferenceUrl();
                newWebReferenceUrl.RelPath = relPath;
                newWebReferenceUrl.UpdateFromURL = url;
                webReferenceUrls.Add(newWebReferenceUrl);
            }
            foreach (DirectoryInfo dirInfo in folder.GetDirectories())
            {
                webReferenceUrls.AddRange(getWebReferenceUrls(dirInfo, relPath));
            }
            return webReferenceUrls.ToArray();
        }


    }
}
