using System;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Text;

namespace compiler
{
    public class MonitorPyWriter : IWriter
    {
        public void Write(string path, TestParser.Node rootNode)
        {
            var sb = new StringBuilder();
            sb.AppendLine($@"# ToDo: Add Python Code");

            foreach (var node in rootNode)
            {
                if (node.Text.StartsWith("constraint:", StringComparison.InvariantCultureIgnoreCase))
                {
                    sb.AppendLine();

                    if (node.Data.Length != 1)
                    {
                        ConsoleLogger.WriteLine("For constraints only 1 t=-Parameter is supportted", Verbosity.Error);
                        throw new ProcessingException();
                    }

                    var time = double.Parse(node.Data[0].Split(">=")[1], CultureInfo.InvariantCulture);
                    sb.AppendLine($"# For time t={time:N} check...");

                    var text = node.Text.Substring("constraint:".Length).Trim();
                    var parts = text.Split("in");
                    var valueToEvaluate = parts[0].Trim();
                    var rangeString = parts[1].Trim();

                    var range = rangeString.TrimStart('[').TrimEnd(']').Split(',').Select(x => x.Trim()).ToList();
                    if (range.Count != 2)
                    {
                        ConsoleLogger.WriteLine("Not exact 2 arguments in range", Verbosity.Error);
                        throw new ProcessingException();
                    }

                    if (valueToEvaluate.StartsWith("Distance", StringComparison.InvariantCultureIgnoreCase))
                    {
                        var elements = valueToEvaluate.Substring("Distance(".Length).TrimEnd(')').Split(',').Select(x => x.Trim()).ToList();
                        if (elements.Count != 2)
                        {
                            ConsoleLogger.WriteLine("Not exact 2 arguments in 'Distance'-Function", Verbosity.Error);
                            throw new ProcessingException();
                        }
                        sb.AppendLine($"# checking constraint for distance between {elements[0]} and {elements[1]}");
                        sb.AppendLine($"# it should be in range of {range[0]} to {range[1]}");
                        sb.AppendLine($"t = {time}");
                        sb.AppendLine($"objectId1 = {elements[0]}");
                        sb.AppendLine($"objectId2 = {elements[1]}");
                        sb.AppendLine($"rangeLeftBorder = {range[0]}");
                        sb.AppendLine($"rangeRightBorder = {range[1]}");
                    }
                    else
                    {
                        ConsoleLogger.WriteLine("Only distance-constraints are allowed so far", Verbosity.Error);
                        throw new ProcessingException();
                        //sb.AppendLine($"# checking constraint for value of {valueToEvaluate}");
                        //sb.AppendLine($"# it should be in range of {range[0]} to {range[1]}");
                    }
                }
            }

            var targetFile = Path.Combine(path, "monitor.py");
            File.WriteAllText(targetFile, sb.ToString());
        }
    }
}