// Created with MonoDevelop
//
//    Copyright (C) 2018 Hiperscan GmbH Dresden, Germany
//
//    This program is free software: you can redistribute it and/or modify
//    it under the terms of the GNU General Public License as published by
//    the Free Software Foundation, either version 3 of the License, or
//    (at your option) any later version.
//
//    This program is distributed in the hope that it will be useful,
//    but WITHOUT ANY WARRANTY; without even the implied warranty of
//    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
//    GNU General Public License for more details.
//
//    You should have received a copy of the GNU General Public License
//    along with this program.  If not, see <http://www.gnu.org/licenses/>.

using System;
using System.Collections.Generic;
using System.IO;
using System.Reflection;
using System.Text;

using Hiperscan.Unix;

namespace Hiperscan.Common.CommandLineArgsParser
{

    public static class AutoCompletion
    {
        private const string PROGRAM_NAME_PLACE_HOLDER       = "PROGRAM_NAME";
        private const string ALL_ARGS_PLACE_HOLDER           = "ALL_ARGS";
        private const string PRE_DEFINED_VALUES_PLACE_HOLDER = "PRE_DEFINED_VALUES";

        public static void CreateAutoCompletionFile(Parser parser, string path)
        {
            Console.WriteLine("Creating auto completion file...");

            FileIO.CreateDirectory(path);

            Stream s = Assembly.GetExecutingAssembly().GetManifestResourceStream("auto_completion_template.txt");
            using (StreamReader sr = new StreamReader(s, System.Text.Encoding.ASCII))
            {
                string content = sr.ReadToEnd();

                List<IOption> items = parser.OptionSection.Parameters;

                string option_flags = AutoCompletion.GetArgs(items);
                string predefined_values = AutoCompletion.GetPredefinedValues(items);

                content = content.Replace(AutoCompletion.PROGRAM_NAME_PLACE_HOLDER, Parser.ProgramName);
                content = content.Replace(AutoCompletion.ALL_ARGS_PLACE_HOLDER, option_flags);
                content = content.Replace(AutoCompletion.PRE_DEFINED_VALUES_PLACE_HOLDER, predefined_values);

                string file = Path.Combine(path, Parser.ProgramName);
                FileIO.Write(content, file, false, Encoding.ASCII);

                Console.WriteLine("Done.");
            }
        }

        private static string GetArgs(List<IOption> items)
        {
            List<string> args = new List<string>();

            foreach(IOption item in items)
            {
                if (item.Undocumented == true)
                    continue;
                
                if (string.IsNullOrEmpty(item.LongName) == false)
                    args.Add(item.LongName);

                if (string.IsNullOrEmpty(item.ShortName) == false)
                    args.Add(item.ShortName);
            }

            return string.Join(" ", args.ToArray());
        }

        private static string GetPredefinedValues(List<IOption> items)
        {
            string predefined_values = string.Empty;

            foreach (IOption item in items)
            {
                if (item.PredefinedValues.Count == 0 || item.Undocumented == true)
                    continue;

                bool long_option_exists = string.IsNullOrEmpty(item.LongName) == false;

                if ( long_option_exists == true)
                    predefined_values += string.Format( "    if [[  \"$prev\" == \"{0}\" ]]", item.LongName);

                if (string.IsNullOrEmpty(item.ShortName) == true)
                {
                    predefined_values += " ; then\n";
                }
                else
                {
                    if ( long_option_exists == false)
                        predefined_values += string.Format( "    if [[  \"$prev\" == \"{0}\" ]] ; then\n", item.ShortName);
                        else
                        predefined_values += string.Format( " || [[  \"$prev\" == \"{0}\" ]] ; then\n", item.ShortName);
                }

                predefined_values += string.Format("        COMPREPLY=( $( compgen -W \"{0}\" -- \"$cur\" ) )\n",
                                                   string.Join(" ", item.PredefinedValues.ToArray()));
                predefined_values += "        return 0\n";
                predefined_values += "    fi\n\n";
                    
            }

            return predefined_values;
        }
    }
}
