<commit_before>﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net.Http;
using System.Text;
using System.Threading.Tasks;

using Newtonsoft.Json.Linq;

namespace KenticoCloud.Deliver
{
    /// <summary>
    /// Class for querying Deliver API.
    /// </summary>
    public class DeliverClient
    {
        private readonly HttpClient httpClient;
        private readonly DeliverUrlBuilder urlBuilder;

        /// <summary>
        /// Constructor for production API.
        /// </summary>
        /// <param name="projectId">Project ID.</param>
        /// <remarks>Production API connects to your published content.</remarks>
        public DeliverClient(string projectId)
        {
            Guid guid;
            if (!Guid.TryParse(projectId, out guid))
            {
                throw new ArgumentException($"The project ID provided seems to be corrupted. Provided value: {projectId}", "projectId");
            }

            urlBuilder = new DeliverUrlBuilder(projectId);
            httpClient = new HttpClient();
        }


        /// <summary>
        /// Constructor for preview API.
        /// </summary>
        /// <param name="projectId">Project ID.</param>
        /// <param name="accessToken">Preview access token.</param>
        /// <remarks>Preview API connects to your unpublished content.</remarks>
        public DeliverClient(string projectId, string accessToken)
        {
            Guid guid;
            if (!Guid.TryParse(projectId, out guid))
            {
                throw new ArgumentException($"The project ID provided seems to be corrupted. Provided value: {projectId}", "projectId");
            }

            urlBuilder = new DeliverUrlBuilder(projectId, accessToken);
            httpClient = new HttpClient();
            httpClient.DefaultRequestHeaders.Add("Authorization", string.Format("Bearer {0}", accessToken));
        }


        /// <summary>
        /// Gets one content item by its codename. This method returns the whole response as JObject.
        /// </summary>
        /// <param name="itemCodename">Content item codename.</param>
        /// <param name="queryParams">Query parameters. For example: "elements=title" or "depth=0"."</param>
        public async Task<JObject> GetItemJsonAsync(string itemCodename, params string[] queryParams)
        {
            if (String.IsNullOrEmpty(itemCodename))
            {
                throw new ArgumentException("Entered item codename is not valid.", "itemCodename");
            }

            var url = urlBuilder.GetItemsUrl(itemCodename, queryParams);
            return await GetDeliverResponseAsync(url);
        }


        /// <summary>
        /// Searches the content repository for items that match the criteria. This method returns the whole response as JObject.
        /// </summary>
        /// <param name="queryParams">Query parameters. For example: "elements=title" or "depth=0".</param>
        public async Task<JObject> GetItemsJsonAsync(params string[] queryParams)
        {
            var url = urlBuilder.GetItemsUrl(queryParams: queryParams);
            return await GetDeliverResponseAsync(url);
        }


        /// <summary>
        /// Gets one content item by its codename.
        /// </summary>
        /// <param name="itemCodename">Content item codename.</param>
        /// <param name="parameters">Query parameters.</param>
        public async Task<DeliverItemResponse> GetItemAsync(string itemCodename, IEnumerable<IFilter> parameters = null)
        {
            if (String.IsNullOrEmpty(itemCodename))
            {
                throw new ArgumentException("Entered item codename is not valid.", "itemCodename");
            }

            var url = urlBuilder.GetItemsUrl(itemCodename, parameters);
            var response = await GetDeliverResponseAsync(url);

            return new DeliverItemResponse(response);
        }


        /// <summary>
        /// Searches the content repository for items that match the filter criteria.
        /// </summary>
        /// <param name="parameters">Query parameters.</param>
        public async Task<DeliverItemListingResponse> GetItemsAsync(IEnumerable<IFilter> parameters = null)
        {
            var url = urlBuilder.GetItemsUrl(filters: parameters);
            var response = await GetDeliverResponseAsync(url);

            return new DeliverItemListingResponse(response);
        }


        /// <summary>
        /// Gets one content type by its codename. This method returns the whole response as JObject.
        /// </summary>
        /// <param name="itemCodename">Content type codename.</param>
        /// <param name="queryParams">Query parameters.</param>
        public async Task<JObject> GetTypeJsonAsync(string typeCodename, params string[] queryParams)
        {
            if (String.IsNullOrEmpty(typeCodename))
            {
                throw new ArgumentException("Entered type codename is not valid.", "typeCodename");
            }

            var url = urlBuilder.GetTypesUrl(typeCodename, queryParams);
            return await GetDeliverResponseAsync(url);
        }


        /// <summary>
        /// Searches the content repository for types that match the criteria. This method returns the whole response as JObject.
        /// </summary>
        /// <param name="queryParams">Query parameters.</param>
        public async Task<JObject> GetTypesJsonAsync(params string[] queryParams)
        {
            var url = urlBuilder.GetTypesUrl(queryParams: queryParams);
            return await GetDeliverResponseAsync(url);
        }


        /// <summary>
        /// Gets one content type by its codename.
        /// </summary>
        /// <param name="itemCodename">Content type codename.</param>
        /// <param name="parameters">Query parameters.</param>
        public async Task<ContentType> GetTypeAsync(string typeCodename, IEnumerable<IFilter> parameters = null)
        {
            if (String.IsNullOrEmpty(typeCodename))
            {
                throw new ArgumentException("Entered type codename is not valid.", "typeCodename");
            }

            var url = urlBuilder.GetTypesUrl(typeCodename, parameters);
            var response = await GetDeliverResponseAsync(url);

            return new ContentType(response);
        }


        /// <summary>
        /// Searches the content repository for types that match the filter criteria.
        /// </summary>
        /// <param name="parameters">Query parameters.</param>
        public async Task<DeliverTypeListingResponse> GetTypesAsync(IEnumerable<IFilter> parameters = null)
        {
            var url = urlBuilder.GetTypesUrl(filters: parameters);<commit_msg>DEL-647 - better checking od project IDs<commit_after>﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net.Http;
using System.Text;
using System.Threading.Tasks;

using Newtonsoft.Json.Linq;

namespace KenticoCloud.Deliver
{
    /// <summary>
    /// Class for querying Deliver API.
    /// </summary>
    public class DeliverClient
    {
        private const int PROJECT_ID_MAX_LENGTH = 36;
        private readonly HttpClient httpClient;
        private readonly DeliverUrlBuilder urlBuilder;

        /// <summary>
        /// Constructor for production API.
        /// </summary>
        /// <param name="projectId">Project ID.</param>
        /// <remarks>Production API connects to your published content.</remarks>
        public DeliverClient(string projectId)
        {
            if (projectId.Length > PROJECT_ID_MAX_LENGTH)
            {
                throw new ArgumentException($"The project ID provided seems to be corrupted. Provided value: {projectId}", nameof(projectId));
            }

            urlBuilder = new DeliverUrlBuilder(projectId);
            httpClient = new HttpClient();
        }


        /// <summary>
        /// Constructor for preview API.
        /// </summary>
        /// <param name="projectId">Project ID.</param>
        /// <param name="accessToken">Preview access token.</param>
        /// <remarks>Preview API connects to your unpublished content.</remarks>
        public DeliverClient(string projectId, string accessToken)
        {
            if (projectId.Length > PROJECT_ID_MAX_LENGTH)
            {
                throw new ArgumentException($"The project ID provided seems to be corrupted. Provided value: {projectId}", nameof(projectId));
            }

            urlBuilder = new DeliverUrlBuilder(projectId, accessToken);
            httpClient = new HttpClient();
            httpClient.DefaultRequestHeaders.Add("Authorization", string.Format("Bearer {0}", accessToken));
        }


        /// <summary>
        /// Gets one content item by its codename. This method returns the whole response as JObject.
        /// </summary>
        /// <param name="itemCodename">Content item codename.</param>
        /// <param name="queryParams">Query parameters. For example: "elements=title" or "depth=0"."</param>
        public async Task<JObject> GetItemJsonAsync(string itemCodename, params string[] queryParams)
        {
            if (String.IsNullOrEmpty(itemCodename))
            {
                throw new ArgumentException("Entered item codename is not valid.", nameof(itemCodename));
            }

            var url = urlBuilder.GetItemsUrl(itemCodename, queryParams);
            return await GetDeliverResponseAsync(url);
        }


        /// <summary>
        /// Searches the content repository for items that match the criteria. This method returns the whole response as JObject.
        /// </summary>
        /// <param name="queryParams">Query parameters. For example: "elements=title" or "depth=0".</param>
        public async Task<JObject> GetItemsJsonAsync(params string[] queryParams)
        {
            var url = urlBuilder.GetItemsUrl(queryParams: queryParams);
            return await GetDeliverResponseAsync(url);
        }


        /// <summary>
        /// Gets one content item by its codename.
        /// </summary>
        /// <param name="itemCodename">Content item codename.</param>
        /// <param name="parameters">Query parameters.</param>
        public async Task<DeliverItemResponse> GetItemAsync(string itemCodename, IEnumerable<IFilter> parameters = null)
        {
            if (String.IsNullOrEmpty(itemCodename))
            {
                throw new ArgumentException("Entered item codename is not valid.", nameof(itemCodename));
            }

            var url = urlBuilder.GetItemsUrl(itemCodename, parameters);
            var response = await GetDeliverResponseAsync(url);

            return new DeliverItemResponse(response);
        }


        /// <summary>
        /// Searches the content repository for items that match the filter criteria.
        /// </summary>
        /// <param name="parameters">Query parameters.</param>
        public async Task<DeliverItemListingResponse> GetItemsAsync(IEnumerable<IFilter> parameters = null)
        {
            var url = urlBuilder.GetItemsUrl(filters: parameters);
            var response = await GetDeliverResponseAsync(url);

            return new DeliverItemListingResponse(response);
        }


        /// <summary>
        /// Gets one content type by its codename. This method returns the whole response as JObject.
        /// </summary>
        /// <param name="itemCodename">Content type codename.</param>
        /// <param name="queryParams">Query parameters.</param>
        public async Task<JObject> GetTypeJsonAsync(string typeCodename, params string[] queryParams)
        {
            if (String.IsNullOrEmpty(typeCodename))
            {
                throw new ArgumentException("Entered type codename is not valid.", nameof(typeCodename));
            }

            var url = urlBuilder.GetTypesUrl(typeCodename, queryParams);
            return await GetDeliverResponseAsync(url);
        }


        /// <summary>
        /// Searches the content repository for types that match the criteria. This method returns the whole response as JObject.
        /// </summary>
        /// <param name="queryParams">Query parameters.</param>
        public async Task<JObject> GetTypesJsonAsync(params string[] queryParams)
        {
            var url = urlBuilder.GetTypesUrl(queryParams: queryParams);
            return await GetDeliverResponseAsync(url);
        }


        /// <summary>
        /// Gets one content type by its codename.
        /// </summary>
        /// <param name="itemCodename">Content type codename.</param>
        /// <param name="parameters">Query parameters.</param>
        public async Task<ContentType> GetTypeAsync(string typeCodename, IEnumerable<IFilter> parameters = null)
        {
            if (String.IsNullOrEmpty(typeCodename))
            {
                throw new ArgumentException("Entered type codename is not valid.", nameof(typeCodename));
            }

            var url = urlBuilder.GetTypesUrl(typeCodename, parameters);
            var response = await GetDeliverResponseAsync(url);

            return new ContentType(response);
        }


        /// <summary>
        /// Searches the content repository for types that match the filter criteria.
        /// </summary>
        /// <param name="parameters">Query parameters.</param>
        public async Task<DeliverTypeListingResponse> GetTypesAsync(IEnumerable<IFilter> parameters = null)
        {
            var url = urlBuilder.GetTypesUrl(filters: parameters);
{'fraction_non_alphanumeric': 0.10480733944954128, 'fraction_numerical': 0.0008073394495412844, 'mean_word_length': 2.2419700214132763, 'pattern_counts': {'":': 0, '<': 139, '<?xml version=': 0, '>': 141, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '6798787', 'n_tokens_mistral': 3401, 'n_tokens_neox': 3324, 'n_words': 943}