/*
The MIT License (MIT)

Copyright (c) 2018 Bogdan Rechi

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 2
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, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
 */

using System;
using System.Reflection;
using System.Linq;
using Newtonsoft.Json.Linq;
using Commons.Files;

namespace Commons.Localizing
{
  /// <summary>
  /// Localized resources holder
  /// </summary>
  public partial class Localization
  {
    /// <summary>
    /// Localizations dictionary (ex: {control, {{en, name}, {ro, name}})
    /// </summary>
    private JObject _localizations;

    private string _defaultLanguage;

    /// <summary>
    /// Initializes a new instance of the Localization class.
    /// </summary>
    /// <param name="assembly">Assembly to load the embedded file from</param>
    /// <param name="defaultLanguage">Default language</param>
    /// <param name="embeddedLocalizationsJsonFile">File containing the localizations</param>
    internal Localization(Assembly assembly, string defaultLanguage, string embeddedLocalizationsJsonFile)
    {
      if (embeddedLocalizationsJsonFile == null)
      {
        throw new NullReferenceException(LocalizationErrors.ErrorFileIsNull);
      }

      try
      {
        var json = File.LoadEmbeddedTextFile(embeddedLocalizationsJsonFile, assembly);

        _defaultLanguage = defaultLanguage;

        _localizations = JObject.Parse(json);
      }
      catch (Exception e)
      {
        throw new Exception(LocalizationErrors.ErrorCannotReadFile, e);
      }
    }

    /// <summary>
    /// Get localized text in default language
    /// </summary>
    /// <param name="key">Key of the localized resource</param>
    /// <returns>Localized text of resource</returns>
    public string this[string key]
    {
      get
      {
        return GetLocalized(_defaultLanguage, key);
      }
    }

    /// <summary>
    /// Get localized text
    /// </summary>
    /// <param name="language">Language of localization</param>
    /// <param name="key">Key of the localized resource</param>
    /// <returns>Localized text of resource</returns>
    public string this[string language, string key]
    {
      get
      {
        return GetLocalized(language, key);
      }
    }

    /// <summary>
    /// Check if a language is supported
    /// </summary>
    /// <param name="language">Language to check</param>
    /// <returns>true if the language is supported, otherwise false</returns>
    public bool IsLanguageSupported(string language)
    {
      return _localizations.SelectTokens($"$.*.{language}").Any();
    }

    private string GetLocalized(string language, string key)
    {
      if (_localizations.SelectToken($"$['{key}']") == null)
      {
        return key;
      }

      var value = _localizations[key][language];

      if (value == null)
      {
        return (string)(_localizations[key][_defaultLanguage] ?? key);
      }
      else
      {
        return (string)value;
      }
    }
  }
}
