using ms_namingservice.Database;
using ms_namingservice.Mapping.ValuesMapping.TempMapping;
using ms_namingservice.Objects;
using ms_namingservice.Objects.SavedData;

namespace ms_namingservice.Mapping.ValuesMapping;

/// <summary>
/// Class handling with method for category mapping.
/// </summary>
public class CategoryMapping
{
    /// <summary>
    /// Represents the logger instance for this class.
    /// </summary>
    private static ILogger Logger = Logging.LoggerFactory.CreateLogger<CategoryMapping>();

    /// <summary>
    /// Returns the category of a given framework.
    /// </summary>
    /// <param name="framework">The name of the framework to map the category to.</param>
    /// <returns>The category mapped to the specified framework.</returns>
    public async static Task<string> GetCategory(string framework)
    {
        if (InputData.Input.Tags[0].Equals("null"))
        {
            return "Other"; //Returns, if no category is recognized from the tag
        }

        try
        {
            //Getting category from the tag in case of MITRE
            string tagCategory = await RulesQuery.GetCategory(InputData.Input.Tags[0], Const.Mitre);
            string category = string.Empty;

            //Getting MITRE category
            if (framework.Equals(Const.Mitre))
            {
                //Converting the tag format to the more user-friendly format (e.g. from attack.command_and_control to Command and Control)
                string mitreCategoryLower = tagCategory.Replace("attack.", "");
                string[] words = mitreCategoryLower.Split('_');
                for (int i = 0; i < words.Length; i++)
                {
                    words[i] = char.ToUpper(words[i][0]) + words[i].Substring(1);
                    if (words[i].Equals("And")) //Used in Command and Control
                    {
                        words[i] = "and";
                    }
                }
                string mitreCategory = string.Join(" ", words);
                category = mitreCategory;
            }
            //Getting ENISA category
            else if (framework.Equals(Const.Enisa))
            {
                string enisaCategory = await MitreToDefaultConvert.GetEnisaCategory(tagCategory); //Converting MITRE to ENISA category
                category = await RulesQuery.GetCategory(enisaCategory, Const.Enisa);
            }
            else
            {
                category = "Other"; //Default category, but should not happen
                Logger.LogInformation("Other category returned.");
            }

            return category; //Returning the value
        }
        catch (Exception ex)
        {
            Logger.LogError("Error: " + ex.Message);
        }

        return "Other"; //If exception is caught other no category is recognised
    }
}