using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Text;
using skyscraper2.TsDuckInterface.Inputs;
using skyscraper2.TsDuckInterface.Outputs;
using skyscraper2.TsDuckInterface.Processors;

namespace skyscraper2.TsDuckInterface
{
    class TspCommandBuilder
    {
        public TspCommandBuilder()
        {
            Processors = new List<TspProcessor>();
            TspPath = "tsp";
        }
        
        public string TspPath { get; set; }

        public TspInput Input { get; set; }
        public TspOutput Output { get; set; }
        public List<TspProcessor> Processors { get; }
        public bool Verbose { get; set; }

        public string GetArguments()
        {
            if (Input == null)
                throw new NullReferenceException("No Input specified!");
            if (Output == null)
                throw new NullReferenceException("No output specified!");

            StringBuilder sb = new StringBuilder();
            if (Verbose)
                sb.Append("-v ");

            sb.Append("-I ");
            sb.Append(Input.ToString());
            sb.Append(" ");

            foreach (TspProcessor processor in Processors)
            {
                sb.Append("-P ");
                sb.Append(processor.ToString());
                sb.Append(" ");
            }

            sb.Append("-O ");
            sb.Append(Output.ToString());
            sb.Append(" ");
            return sb.ToString();
        }

        public int ExecuteAndWait()
        {
            

            Process tsp = new Process();
            tsp.StartInfo.FileName = TspPath;
            tsp.StartInfo.Arguments = GetArguments();

            tsp.Start();
            tsp.WaitForExit();

            return tsp.ExitCode;
        }

        public static FileInfo TsToXml(FileInfo ts)
        {
            string tempFileName = Path.GetTempFileName();
            FileInfo fi = new FileInfo(tempFileName);
            if (fi.Exists)
                fi.Delete();
            
            TspCommandBuilder tcb = new TspCommandBuilder();
            tcb.Verbose = true;
            tcb.Input = new FileInput(ts);
            tcb.Output = new DropOutput();
            //tcb.Processors.Add(new HistoryProcessor());
            tcb.Processors.Add(new TablesProcessor(true, true, fi, true));
            int result = tcb.ExecuteAndWait();
            switch (result)
            {
                case 0:
                    break;
                case 1:
                    Console.WriteLine("tsp encountered an error. Ignoring this stream.");
                    fi.Delete();
                    return null;
                case -1073741819:
                    Console.WriteLine("tsp encountered an access violation. Ignoring this stream.");
                    fi.Delete();
                    return null;
                default:
                    throw new NotImplementedException(result.ToString());
            }
            return fi;
        }
    }
}
