<commit_before>﻿//-----------------------------------------------------------------------
// <copyright file="SonarWebServices.cs" company="SonarSource SA and Microsoft Corporation">
//   (c) SonarSource SA and Microsoft Corporation.  All rights reserved.
// </copyright>
//-----------------------------------------------------------------------

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Net;
using Newtonsoft.Json.Linq;

namespace Sonar.FxCopRuleset
{
    public class SonarWebService : IDisposable
    {
        private readonly string Server;
        private readonly string Username;
        private readonly string Password;
        private readonly string Language;
        private readonly string Repository;
        private readonly WebClient Client;

        public SonarWebService(string server, string username, string password, string language, string repository)
        {
            Server = server.EndsWith("/") ? server.Substring(0, server.Length - 1) : server;
            Username = username;
            Password = password;
            Language = language;
            Repository = repository;

            Client = new WebClient();
            if (username != null && password != null)
            {
                if (username.Contains(':'))
                {
                    throw new ArgumentException("username cannot contain the ':' character due to basic authentication limitations");
                }
                if (!IsAscii(username) || !IsAscii(password))
                {
                    throw new ArgumentException("username and password should contain only ASCII characters due to basic authentication limitations");
                }

                var credentials = string.Format("{0}:{1}", username, password);
                credentials = Convert.ToBase64String(Encoding.ASCII.GetBytes(credentials));
                Client.Headers[HttpRequestHeader.Authorization] = "Basic " + credentials;
            }
        }

        private static bool IsAscii(string s)
        {
            return !s.Any(c => c > sbyte.MaxValue);
        }

        /// <summary>
        /// Get the name of the quality profile (of the given language) to be used by the given project key
        /// </summary>
        public string GetQualityProfile(string projectKey)
        {
            string contents;
            var ws = GetUrl("/api/profiles/list?language={0}&project={1}", Language, projectKey);
            if (!TryDownloadIfExists(ws, out contents))
            {
                ws = GetUrl("/api/profiles/list?language={0}", Language);
                contents = Download(ws);
            }
            var profiles = JArray.Parse(contents);
            // TODO What is profiles is empty?
            var profile = profiles.Count > 1 ? profiles.Where(p => "True".Equals(p["default"].ToString())).Single() : profiles[0];
            return profile["name"].ToString();
        }

        /// <summary>
        /// Get all the active rules (of the given language and repository) in the given quality profile name
        /// </summary>
        public IEnumerable<string> GetActiveRuleKeys(string qualityProfile)
        {
            var ws = GetUrl("/api/profiles/index?language={0}&name={1}", Language, qualityProfile);
            var contents = Download(ws);

            var profiles = JArray.Parse(contents);
            var rules = profiles.Single()["rules"];
            var keys = rules == null ? Enumerable.Empty<string>() : rules.Where(r => Repository.Equals(r["repo"].ToString())).Select(r => r["key"].ToString());

            return keys;
        }

        /// <summary>
        /// Get the key -> internal keys mapping (of the given language and repository)
        /// </summary>
        public IDictionary<string, string> GetInternalKeys()
        {
            var ws = GetUrl("/api/rules/search?activation=true&f=internalKey&ps={0}&repositories={1}", int.MaxValue.ToString(), Repository);
            var contents = Download(ws);

            var rules = JObject.Parse(contents);
            var keysToIds = rules["rules"].ToDictionary(r => r["key"].ToString(), r => r["internalKey"] != null ? r["internalKey"].ToString() : null);

            return keysToIds;
        }

        public void Dispose()
        {<commit_msg>FxCopRuleset: Remove useless 'activation' WS parameter<commit_after>﻿//-----------------------------------------------------------------------
// <copyright file="SonarWebServices.cs" company="SonarSource SA and Microsoft Corporation">
//   (c) SonarSource SA and Microsoft Corporation.  All rights reserved.
// </copyright>
//-----------------------------------------------------------------------

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Net;
using Newtonsoft.Json.Linq;

namespace Sonar.FxCopRuleset
{
    public class SonarWebService : IDisposable
    {
        private readonly string Server;
        private readonly string Username;
        private readonly string Password;
        private readonly string Language;
        private readonly string Repository;
        private readonly WebClient Client;

        public SonarWebService(string server, string username, string password, string language, string repository)
        {
            Server = server.EndsWith("/") ? server.Substring(0, server.Length - 1) : server;
            Username = username;
            Password = password;
            Language = language;
            Repository = repository;

            Client = new WebClient();
            if (username != null && password != null)
            {
                if (username.Contains(':'))
                {
                    throw new ArgumentException("username cannot contain the ':' character due to basic authentication limitations");
                }
                if (!IsAscii(username) || !IsAscii(password))
                {
                    throw new ArgumentException("username and password should contain only ASCII characters due to basic authentication limitations");
                }

                var credentials = string.Format("{0}:{1}", username, password);
                credentials = Convert.ToBase64String(Encoding.ASCII.GetBytes(credentials));
                Client.Headers[HttpRequestHeader.Authorization] = "Basic " + credentials;
            }
        }

        private static bool IsAscii(string s)
        {
            return !s.Any(c => c > sbyte.MaxValue);
        }

        /// <summary>
        /// Get the name of the quality profile (of the given language) to be used by the given project key
        /// </summary>
        public string GetQualityProfile(string projectKey)
        {
            string contents;
            var ws = GetUrl("/api/profiles/list?language={0}&project={1}", Language, projectKey);
            if (!TryDownloadIfExists(ws, out contents))
            {
                ws = GetUrl("/api/profiles/list?language={0}", Language);
                contents = Download(ws);
            }
            var profiles = JArray.Parse(contents);
            // TODO What is profiles is empty?
            var profile = profiles.Count > 1 ? profiles.Where(p => "True".Equals(p["default"].ToString())).Single() : profiles[0];
            return profile["name"].ToString();
        }

        /// <summary>
        /// Get all the active rules (of the given language and repository) in the given quality profile name
        /// </summary>
        public IEnumerable<string> GetActiveRuleKeys(string qualityProfile)
        {
            var ws = GetUrl("/api/profiles/index?language={0}&name={1}", Language, qualityProfile);
            var contents = Download(ws);

            var profiles = JArray.Parse(contents);
            var rules = profiles.Single()["rules"];
            var keys = rules == null ? Enumerable.Empty<string>() : rules.Where(r => Repository.Equals(r["repo"].ToString())).Select(r => r["key"].ToString());

            return keys;
        }

        /// <summary>
        /// Get the key -> internal keys mapping (of the given language and repository)
        /// </summary>
        public IDictionary<string, string> GetInternalKeys()
        {
            var ws = GetUrl("/api/rules/search?f=internalKey&ps={0}&repositories={1}", int.MaxValue.ToString(), Repository);
            var contents = Download(ws);

            var rules = JObject.Parse(contents);
            var keysToIds = rules["rules"].ToDictionary(r => r["key"].ToString(), r => r["internalKey"] != null ? r["internalKey"].ToString() : null);

            return keysToIds;
        }

        public void Dispose()
        {
{'fraction_non_alphanumeric': 0.144288805375242, 'fraction_numerical': 0.0034164673727365906, 'mean_word_length': 1.9549125168236878, 'pattern_counts': {'":': 0, '<': 25, '<?xml version=': 0, '>': 43, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 8, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '7475043', 'n_tokens_mistral': 2120, 'n_tokens_neox': 2034, 'n_words': 597}