﻿
using Microsoft.Build.Evaluation;
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.CSharp;
using Microsoft.CodeAnalysis.CSharp.Syntax;
using RS.Common;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;

namespace RS.JSProxyGenerator
{
    public static class ProxyGenerator
    {
        public const string ShortProxyPath = "Scripts\\Proxy.js";

        public static void Generate(Microsoft.Build.Evaluation.Project project, List<Microsoft.Build.Evaluation.Project> siblings)
        {
            string message = string.Empty;

            try
            {
                //get all .cs in solution
                SolutionTypesManager.Classes = new List<ClassDeclarationSyntax>();
                SolutionTypesManager.Interfaces = new List<InterfaceDeclarationSyntax>();

                foreach (var proj in siblings)
                {

                    var items = proj.Items.Where(it => it.EvaluatedInclude.EndsWith(".cs"));
                    foreach (var item in items)
                    {
                        string filepath = Path.Combine(proj.DirectoryPath, item.EvaluatedInclude);
                        string code = File.ReadAllText(filepath);
                        SyntaxTree tree = CSharpSyntaxTree.ParseText(code);
                        var root = (CompilationUnitSyntax)tree.GetRoot();

                        var classes = root.DescendantNodes().OfType<ClassDeclarationSyntax>().ToList();
                        if (classes.Count > 0)
                            SolutionTypesManager.AddClasses(classes);

                        if (proj == project)
                        {
                            var interfaces = root.DescendantNodes().OfType<InterfaceDeclarationSyntax>().ToList();
                            if (interfaces.Count > 0)
                                SolutionTypesManager.AddInterfaces(interfaces);
                        }
                    }
                }

                EndPointClassesIdentifier endpointidentifier = new EndPointClassesIdentifier();
                List<EndPointClass> endpoints = null;

                List<EndPointClass> ControllerEndpoints = endpointidentifier.GetEndpoints(project);

                if (ControllerEndpoints != null)
                    endpoints = ControllerEndpoints;

                List<EndPointClass> WCFEndpoints = endpointidentifier.GetWCFEndpoints();

                if (endpoints == null)
                    endpoints = WCFEndpoints;
                else if (WCFEndpoints != null)
                    endpoints = (endpoints.Concat(WCFEndpoints)).ToList();

                if (endpoints == null || endpoints.Count == 0)
                {
                    throw new HandledException(" doesn't contain endpoints.");
                }

                TemplateCreator tc = new TemplateCreator(endpoints);
                
                string projectDir = project.DirectoryPath;
                string proxyPath = Path.Combine(projectDir, ShortProxyPath);

                using (StreamWriter file = new StreamWriter(proxyPath))
                {
                    file.Write(tc.newProxy);
                }

                ProjectItem pItem = project.Items.FirstOrDefault(it => it.EvaluatedInclude == ShortProxyPath);
                if (pItem == null)
                {
                    project.AddItem("Content", ShortProxyPath);
                    project.Save();
                }

                //free up stuff?
                SolutionTypesManager.CleanUp();
            }
            catch (Exception ex)
            {
                throw new HandledException(ex.Message);
            }
        }
    }
}