<commit_before>﻿using AngleSharp;
using AngleSharp.Dom.Html;
using AngleSharp.Extensions;
using Discord;
using Discord.Commands;
using NadekoBot.Attributes;
using NadekoBot.Extensions;
using NadekoBot.Modules.Searches.Models;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using NLog;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net.Http;
using System.Threading;
using System.Threading.Tasks;

namespace NadekoBot.Modules.Searches
{
    public partial class Searches
    {
        [Group]
        public class AnimeSearchCommands : ModuleBase
        {
            private static Timer anilistTokenRefresher { get; }
            private static Logger _log { get; }
            private static string anilistToken { get; set; }

            static AnimeSearchCommands()
            {
                _log = LogManager.GetCurrentClassLogger();
                anilistTokenRefresher = new Timer(async (state) =>
                {
                    try
                    {
                        var headers = new Dictionary<string, string> {
                        {"grant_type", "client_credentials"},
                        {"client_id", "kwoth-w0ki9"},
                        {"client_secret", "<KEY>"},
                    };

                        using (var http = new HttpClient())
                        {
                            http.AddFakeHeaders();
                            var formContent = new FormUrlEncodedContent(headers);
                            var response = await http.PostAsync("http://anilist.co/api/auth/access_token", formContent).ConfigureAwait(false);
                            var stringContent = await response.Content.ReadAsStringAsync().ConfigureAwait(false);
                            anilistToken = JObject.Parse(stringContent)["access_token"].ToString();
                        }
                    }
                    catch (Exception ex)
                    {
                        _log.Error(ex);
                    }
                }, null, TimeSpan.FromSeconds(0), TimeSpan.FromMinutes(29));
            }

            [NadekoCommand, Usage, Description, Aliases]
            [Priority(1)]
            public async Task Mal([Remainder] string name)
            {
                if (string.IsNullOrWhiteSpace(name))
                    return;

                var fullQueryLink = "https://myanimelist.net/profile/" + name;

                var config = Configuration.Default.WithDefaultLoader();
                var document = await BrowsingContext.New(config).OpenAsync(fullQueryLink);

                var imageElem = document.QuerySelector("body > div#myanimelist > div.wrapper > div#contentWrapper > div#content > div.content-container > div.container-left > div.user-profile > div.user-image > img");
                var imageUrl = ((IHtmlImageElement)imageElem)?.Source ?? "http://icecream.me/uploads/870b03f36b59cc16ebfe314ef2dde781.png";

                var stats = document.QuerySelectorAll("body > div#myanimelist > div.wrapper > div#contentWrapper > div#content > div.content-container > div.container-right > div#statistics > div.user-statistics-stats > div.stats > div.clearfix > ul.stats-status > li > span").Select(x => x.InnerHtml).ToList();

                var favorites = document.QuerySelectorAll("div.user-favorites > div.di-tc");

                var favAnime = "No favorite anime yet";
                if (favorites[0].QuerySelector("p") == null)
                    favAnime = string.Join("\n", favorites[0].QuerySelectorAll("ul > li > div.di-tc.va-t > a")
                       .Shuffle()
                       .Take(3)
                       .Select(x =>
                       {
                           var elem = (IHtmlAnchorElement)x;
                           return $"[{elem.InnerHtml}]({elem.Href})";
                       }));

                //var favManga = "No favorite manga yet.";
                //if (favorites[1].QuerySelector("p") == null)
                //    favManga = string.Join("\n", favorites[1].QuerySelectorAll("ul > li > div.di-tc.va-t > a")
                //       .Take(3)
                //       .Select(x =>
                //       {
                //           var elem = (IHtmlAnchorElement)x;
                //           return $"[{elem.InnerHtml}]({elem.Href})";
                //       }));

                var info = document.QuerySelectorAll("ul.user-status:nth-child(3) > li")
                    .Select(x => Tuple.Create(x.Children[0].InnerHtml, x.Children[1].InnerHtml))
                    .ToList();

                var daysAndMean = document.QuerySelectorAll("div.anime:nth-child(1) > div:nth-child(2) > div")
                    .Select(x => x.TextContent.Split(':').Select(y => y.Trim()).ToArray())
                    .ToArray();

                var embed = new EmbedBuilder()
                    .WithOkColor()
                    .WithTitle($"{name}'s MAL profile")
                    .AddField(efb => efb.WithName("💚 Watching").WithValue(stats[0]).WithIsInline(true))
                    .AddField(efb => efb.WithName("💙 Completed").WithValue(stats[1]).WithIsInline(true));
                if (info.Count < 3)
                    embed.AddField(efb => efb.WithName("💛 On-Hold").WithValue(stats[2]).WithIsInline(true));
                embed
                    .AddField(efb => efb.WithName("💔 Dropped").WithValue(stats[3]).WithIsInline(true))
                    .AddField(efb => efb.WithName("⚪ Plan to watch").WithValue(stats[4]).WithIsInline(true))
                    .AddField(efb => efb.WithName("🕐 " + daysAndMean[0][0]).WithValue(daysAndMean[0][1]).WithIsInline(true))
                    .AddField(efb => efb.WithName("📊 " + daysAndMean[1][0]).WithValue(daysAndMean[1][1]).WithIsInline(true))
                    .AddField(efb => efb.WithName(MalInfoToEmoji(info[0].Item1) + " " + info[0].Item1).WithValue(info[0].Item2.TrimTo(20)).WithIsInline(true))
                    .AddField(efb => efb.WithName(MalInfoToEmoji(info[1].Item1) + " " + info[1].Item1).WithValue(info[1].Item2.TrimTo(20)).WithIsInline(true));
                if (info.Count > 2)
                    embed.AddField(efb => efb.WithName(MalInfoToEmoji(info[2].Item1) + " " + info[2].Item1).WithValue(info[2].Item2.TrimTo(20)).WithIsInline(true));
                //if(info.Count > 3)
                //    embed.AddField(efb => efb.WithName(MalInfoToEmoji(info[3].Item1) + " " + info[3].Item1).WithValue(info[3].Item2).WithIsInline(true))
                embed
                    .WithDescription($@"<commit_msg>Fixed ~mal command for mal supporters<commit_after>﻿using AngleSharp;
using AngleSharp.Dom.Html;
using AngleSharp.Extensions;
using Discord;
using Discord.Commands;
using NadekoBot.Attributes;
using NadekoBot.Extensions;
using NadekoBot.Modules.Searches.Models;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using NLog;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net.Http;
using System.Threading;
using System.Threading.Tasks;

namespace NadekoBot.Modules.Searches
{
    public partial class Searches
    {
        [Group]
        public class AnimeSearchCommands : ModuleBase
        {
            private static Timer anilistTokenRefresher { get; }
            private static Logger _log { get; }
            private static string anilistToken { get; set; }

            static AnimeSearchCommands()
            {
                _log = LogManager.GetCurrentClassLogger();
                anilistTokenRefresher = new Timer(async (state) =>
                {
                    try
                    {
                        var headers = new Dictionary<string, string> {
                        {"grant_type", "client_credentials"},
                        {"client_id", "kwoth-w0ki9"},
                        {"client_secret", "<KEY>"},
                    };

                        using (var http = new HttpClient())
                        {
                            http.AddFakeHeaders();
                            var formContent = new FormUrlEncodedContent(headers);
                            var response = await http.PostAsync("http://anilist.co/api/auth/access_token", formContent).ConfigureAwait(false);
                            var stringContent = await response.Content.ReadAsStringAsync().ConfigureAwait(false);
                            anilistToken = JObject.Parse(stringContent)["access_token"].ToString();
                        }
                    }
                    catch (Exception ex)
                    {
                        _log.Error(ex);
                    }
                }, null, TimeSpan.FromSeconds(0), TimeSpan.FromMinutes(29));
            }

            [NadekoCommand, Usage, Description, Aliases]
            [Priority(1)]
            public async Task Mal([Remainder] string name)
            {
                if (string.IsNullOrWhiteSpace(name))
                    return;

                var fullQueryLink = "https://myanimelist.net/profile/" + name;

                var config = Configuration.Default.WithDefaultLoader();
                var document = await BrowsingContext.New(config).OpenAsync(fullQueryLink);

                var imageElem = document.QuerySelector("body > div#myanimelist > div.wrapper > div#contentWrapper > div#content > div.content-container > div.container-left > div.user-profile > div.user-image > img");
                var imageUrl = ((IHtmlImageElement)imageElem)?.Source ?? "http://icecream.me/uploads/870b03f36b59cc16ebfe314ef2dde781.png";

                var stats = document.QuerySelectorAll("body > div#myanimelist > div.wrapper > div#contentWrapper > div#content > div.content-container > div.container-right > div#statistics > div.user-statistics-stats > div.stats > div.clearfix > ul.stats-status > li > span").Select(x => x.InnerHtml).ToList();

                var favorites = document.QuerySelectorAll("div.user-favorites > div.di-tc");

                var favAnime = "No favorite anime yet";
                if (favorites[0].QuerySelector("p") == null)
                    favAnime = string.Join("\n", favorites[0].QuerySelectorAll("ul > li > div.di-tc.va-t > a")
                       .Shuffle()
                       .Take(3)
                       .Select(x =>
                       {
                           var elem = (IHtmlAnchorElement)x;
                           return $"[{elem.InnerHtml}]({elem.Href})";
                       }));

                //var favManga = "No favorite manga yet.";
                //if (favorites[1].QuerySelector("p") == null)
                //    favManga = string.Join("\n", favorites[1].QuerySelectorAll("ul > li > div.di-tc.va-t > a")
                //       .Take(3)
                //       .Select(x =>
                //       {
                //           var elem = (IHtmlAnchorElement)x;
                //           return $"[{elem.InnerHtml}]({elem.Href})";
                //       }));

                var info = document.QuerySelectorAll("ul.user-status:nth-child(3) > li.clearfix")
                    .Select(x => Tuple.Create(x.Children[0].InnerHtml, x.Children[1].InnerHtml))
                    .ToList();

                var daysAndMean = document.QuerySelectorAll("div.anime:nth-child(1) > div:nth-child(2) > div")
                    .Select(x => x.TextContent.Split(':').Select(y => y.Trim()).ToArray())
                    .ToArray();

                var embed = new EmbedBuilder()
                    .WithOkColor()
                    .WithTitle($"{name}'s MAL profile")
                    .AddField(efb => efb.WithName("💚 Watching").WithValue(stats[0]).WithIsInline(true))
                    .AddField(efb => efb.WithName("💙 Completed").WithValue(stats[1]).WithIsInline(true));
                if (info.Count < 3)
                    embed.AddField(efb => efb.WithName("💛 On-Hold").WithValue(stats[2]).WithIsInline(true));
                embed
                    .AddField(efb => efb.WithName("💔 Dropped").WithValue(stats[3]).WithIsInline(true))
                    .AddField(efb => efb.WithName("⚪ Plan to watch").WithValue(stats[4]).WithIsInline(true))
                    .AddField(efb => efb.WithName("🕐 " + daysAndMean[0][0]).WithValue(daysAndMean[0][1]).WithIsInline(true))
                    .AddField(efb => efb.WithName("📊 " + daysAndMean[1][0]).WithValue(daysAndMean[1][1]).WithIsInline(true))
                    .AddField(efb => efb.WithName(MalInfoToEmoji(info[0].Item1) + " " + info[0].Item1).WithValue(info[0].Item2.TrimTo(20)).WithIsInline(true))
                    .AddField(efb => efb.WithName(MalInfoToEmoji(info[1].Item1) + " " + info[1].Item1).WithValue(info[1].Item2.TrimTo(20)).WithIsInline(true));
                if (info.Count > 2)
                    embed.AddField(efb => efb.WithName(MalInfoToEmoji(info[2].Item1) + " " + info[2].Item1).WithValue(info[2].Item2.TrimTo(20)).WithIsInline(true));
                //if(info.Count > 3)
                //    embed.AddField(efb => efb.WithName(MalInfoToEmoji(info[3].Item1) + " " + info[3].Item1).WithValue(info[3].Item2).WithIsInline(true))
                embed
                    .WithDescription($@"
{'fraction_non_alphanumeric': 0.13310141420252591, 'fraction_numerical': 0.012251380170914317, 'mean_word_length': 1.7555740779329028, 'pattern_counts': {'":': 0, '<': 9, '<?xml version=': 0, '>': 111, 'https://': 2, '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': '3226674', 'n_tokens_mistral': 3904, 'n_tokens_neox': 3689, 'n_words': 578}