using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using VDS.RDF;
using VDS.RDF.Query;
using VDS.RDF.Parsing;
using VDS.RDF.Writing;

using Tools.Config;

namespace ModelData.BusinessModel.RDF
{
    /*!
            \defgroup RDF Обращение к онтологии
            \brief Группа классов, работающих непосредственно с точками доступа и онтологией.

            Содержит класс для отправки запроса/получения ответа и статичный класс со всеми возможными запросами. 
            @{
        */

    /// \class  RDFQuery
    ///
    /// \brief  Выполняет отправку запроса и получение результата.
    ///
    /// \author Denis
    /// \date   31.03.2019

    public class RDFQuery
    {     
        /// \enum   QueryType
        ///
        /// \brief  Тип запроса, который будет использован
        /// В зависимости от типа запроса выбирается текст запроса, используемые параметры и точка обращения.

        public enum QueryType
        {
            Years,              ///< Запрос максимального и минимального годов. Параметры не требуются. Вернет одну строку.
            AllSettlements,     ///< Запрос всех поселений. Нужен для создания точек карты. Два параметра: требуемые года. Вернет большой список.
            SettlementInfo,     ///< Запрос все информации об одном поселении. Один параметр: URL поселения. Вернет список, где одна строка про поселение и все остальные строки про измененные поселения.
            SubName,            ///< Запрос всех имен поселений, часть названия которых совпадает с параметром. Один параметр: подстрока для поиска. Вернет большой список.
            AllSettlementTypes, ///< Запрос всех возможных типов поселений за все периоды. Вернет большой список.
            AllRegions          ///< Запрос всех возможных административных единиц (регионов) за все периоды. Вернет большой список.
        };

        /// \fn public static List<SparqlResult> GetData(QueryType queryType, string[] args = null)
        ///
        /// \brief  Получить результат запроса
        /// Общий метод отправки запроса к точке доступа. Запрос и его параметры регулируются параметрами метода.
        /// Точка доступа регулируется типом запроса.
        /// \author Denis
        /// \date   31.03.2019
        ///
        /// \exception  Exception "не подходящий тип запроса".
        ///
        /// \param  queryType   Тип запроса.
        /// \param  args        (необязательный) Массив строк, используемый в качестве параметров запросов.
        ///
        /// \returns    The data.

        public static List<SparqlResult> GetData(QueryType queryType, string[] args = null)
        {
            string exQuery;
            string endpointURI;
            var Config = ConfigManager.Get();
            try
            {
                switch (queryType)
                {
                    case QueryType.Years:
                        {
                            exQuery = Queries.Years();
                            endpointURI = Config.SPARQL_Query_Endpoint;
                        } break;
                    case QueryType.AllSettlements:
                        {
                            exQuery = Queries.AllSettlementsInInterval(args[0], args[1]);
                            endpointURI = Config.SPARQL_Query_Endpoint;
                        } break;
                    case QueryType.SettlementInfo:
                        {
                            exQuery = Queries.InfoAboutSettlement(args[0]);
                            endpointURI = Config.SPARQL_Query_Endpoint;
                        } break;
                    case QueryType.SubName:
                        {
                            exQuery = Queries.AllSettlementsName(args[0]);
                            endpointURI = Config.SPARQL_Query_Endpoint;
                        } break;
                    case QueryType.AllSettlementTypes:
                        {
                            exQuery = Queries.AllSettlementTypes();
                            endpointURI = Config.SPARQL_Query_Endpoint;
                        }
                        break;
                    case QueryType.AllRegions:
                        {
                            exQuery = Queries.AllRegions();
                            endpointURI = Config.SPARQL_Query_Endpoint;
                        }
                        break;
                    default: throw new Exception("Invalid argument: queryType = " + queryType.ToString());
                }
            }
            catch (Exception e)
            {
                Console.WriteLine(e.Message);
                Console.ReadKey();
                throw;
            }
            //Create endpoint and make our query
            SparqlRemoteEndpoint endpoint = new SparqlRemoteEndpoint(new Uri(endpointURI));
            SparqlResultSet results = endpoint.QueryWithResultSet(exQuery);

            return results.Results;
        }
    }
    /// @}
}
