<commit_before>﻿// Copyright (c) ppy Pty Ltd <<EMAIL>>. Licensed under the MIT Licence.
// See the LICENCE file in the repository root for full licence text.

using System;
using Newtonsoft.Json;
using osu.Game.Beatmaps;
using osu.Game.Rulesets;

#nullable enable

namespace osu.Game.Online.API.Requests.Responses
{
    public class APIBeatmap : IBeatmapInfo, IBeatmapOnlineInfo
    {
        [JsonProperty(@"id")]
        public int OnlineID { get; set; }

        [JsonProperty(@"beatmapset_id")]
        public int OnlineBeatmapSetID { get; set; }

        [JsonProperty(@"status")]
        public BeatmapSetOnlineStatus Status { get; set; }

        [JsonProperty("checksum")]
        public string Checksum { get; set; } = string.Empty;

        [JsonProperty(@"user_id")]
        public int AuthorID { get; set; }

        [JsonProperty(@"beatmapset")]
        public APIBeatmapSet? BeatmapSet { get; set; }

        [JsonProperty(@"playcount")]
        public int PlayCount { get; set; }

        [JsonProperty(@"passcount")]
        public int PassCount { get; set; }

        [JsonProperty(@"mode_int")]
        public int RulesetID { get; set; }

        [JsonProperty(@"difficulty_rating")]
        public double StarRating { get; set; }

        [JsonProperty(@"drain")]
        private float drainRate { get; set; }

        [JsonProperty(@"cs")]
        private float circleSize { get; set; }

        [JsonProperty(@"ar")]
        private float approachRate { get; set; }

        [JsonProperty(@"accuracy")]
        private float overallDifficulty { get; set; }

        [JsonIgnore]
        public double Length { get; set; }

        [JsonProperty(@"total_length")]
        private double lengthInSeconds
        {
            get => TimeSpan.FromMilliseconds(Length).TotalSeconds;
            set => Length = TimeSpan.FromSeconds(value).TotalMilliseconds;
        }

        [JsonProperty(@"count_circles")]
        public int CircleCount { get; set; }

        [JsonProperty(@"count_sliders")]
        public int SliderCount { get; set; }

        [JsonProperty(@"version")]
        public string DifficultyName { get; set; } = string.Empty;

        [JsonProperty(@"failtimes")]
        public APIFailTimes? FailTimes { get; set; }

        [JsonProperty(@"max_combo")]
        public int? MaxCombo { get; set; }

        public double BPM { get; set; }

        public virtual BeatmapInfo ToBeatmapInfo(RulesetStore rulesets)
        {
            var set = BeatmapSet?.ToBeatmapSet(rulesets);

            return new BeatmapInfo
            {
                Metadata = set?.Metadata ?? new BeatmapMetadata(),
                Ruleset = rulesets.GetRuleset(RulesetID),
                StarDifficulty = StarRating,
                OnlineBeatmapID = OnlineID,
                Version = DifficultyName,
                // this is actually an incorrect mapping (Length is calculated as drain length in lazer's import process, see BeatmapManager.calculateLength).
                Length = Length,
                Status = Status,
                MD5Hash = Checksum,
                BeatmapSet = set,
                MaxCombo = MaxCombo,
                BaseDifficulty = new BeatmapDifficulty
                {
                    DrainRate = drainRate,
                    CircleSize = circleSize,
                    ApproachRate = approachRate,
                    OverallDifficulty = overallDifficulty,
                },
                OnlineInfo = this,
            };
        }

        #region Implementation of IBeatmapInfo

        public IBeatmapMetadataInfo Metadata => (BeatmapSet as IBeatmapSetInfo)?.Metadata ?? new BeatmapMetadata();

        public IBeatmapDifficultyInfo Difficulty => new BeatmapDifficulty
        {
            DrainRate = drainRate,
            CircleSize = circleSize,
            ApproachRate = approachRate,
            OverallDifficulty = overallDifficulty,
        };

        IBeatmapSetInfo? IBeatmapInfo.BeatmapSet => BeatmapSet;

        public string MD5Hash => Checksum;

        public IRulesetInfo Ruleset => new RulesetInfo { ID = RulesetID };

        [JsonIgnore]
        public string Hash => throw new NotImplementedException();

        #endregion
    }
}<commit_msg>Expose more pieces of `APIBeatmap` for testing purposes<commit_after>﻿// Copyright (c) ppy <NAME> <<EMAIL>>. Licensed under the MIT Licence.
// See the LICENCE file in the repository root for full licence text.

using System;
using Newtonsoft.Json;
using osu.Game.Beatmaps;
using osu.Game.Rulesets;

#nullable enable

namespace osu.Game.Online.API.Requests.Responses
{
    public class APIBeatmap : IBeatmapInfo, IBeatmapOnlineInfo
    {
        [JsonProperty(@"id")]
        public int OnlineID { get; set; }

        [JsonProperty(@"beatmapset_id")]
        public int OnlineBeatmapSetID { get; set; }

        [JsonProperty(@"status")]
        public BeatmapSetOnlineStatus Status { get; set; }

        [JsonProperty("checksum")]
        public string Checksum { get; set; } = string.Empty;

        [JsonProperty(@"user_id")]
        public int AuthorID { get; set; }

        [JsonProperty(@"beatmapset")]
        public APIBeatmapSet? BeatmapSet { get; set; }

        [JsonProperty(@"playcount")]
        public int PlayCount { get; set; }

        [JsonProperty(@"passcount")]
        public int PassCount { get; set; }

        [JsonProperty(@"mode_int")]
        public int RulesetID { get; set; }

        [JsonProperty(@"difficulty_rating")]
        public double StarRating { get; set; }

        [JsonProperty(@"drain")]
        public float DrainRate { get; set; }

        [JsonProperty(@"cs")]
        public float CircleSize { get; set; }

        [JsonProperty(@"ar")]
        public float ApproachRate { get; set; }

        [JsonProperty(@"accuracy")]
        public float OverallDifficulty { get; set; }

        [JsonIgnore]
        public double Length { get; set; }

        [JsonProperty(@"total_length")]
        private double lengthInSeconds
        {
            get => TimeSpan.FromMilliseconds(Length).TotalSeconds;
            set => Length = TimeSpan.FromSeconds(value).TotalMilliseconds;
        }

        [JsonProperty(@"count_circles")]
        public int CircleCount { get; set; }

        [JsonProperty(@"count_sliders")]
        public int SliderCount { get; set; }

        [JsonProperty(@"version")]
        public string DifficultyName { get; set; } = string.Empty;

        [JsonProperty(@"failtimes")]
        public APIFailTimes? FailTimes { get; set; }

        [JsonProperty(@"max_combo")]
        public int? MaxCombo { get; set; }

        public double BPM { get; set; }

        public virtual BeatmapInfo ToBeatmapInfo(RulesetStore rulesets)
        {
            var set = BeatmapSet?.ToBeatmapSet(rulesets);

            return new BeatmapInfo
            {
                Metadata = set?.Metadata ?? new BeatmapMetadata(),
                Ruleset = rulesets.GetRuleset(RulesetID),
                StarDifficulty = StarRating,
                OnlineBeatmapID = OnlineID,
                Version = DifficultyName,
                // this is actually an incorrect mapping (Length is calculated as drain length in lazer's import process, see BeatmapManager.calculateLength).
                Length = Length,
                Status = Status,
                MD5Hash = Checksum,
                BeatmapSet = set,
                MaxCombo = MaxCombo,
                BaseDifficulty = new BeatmapDifficulty
                {
                    DrainRate = drainRate,
                    CircleSize = circleSize,
                    ApproachRate = approachRate,
                    OverallDifficulty = overallDifficulty,
                },
                OnlineInfo = this,
            };
        }

        #region Implementation of IBeatmapInfo

        public IBeatmapMetadataInfo Metadata => (BeatmapSet as IBeatmapSetInfo)?.Metadata ?? new BeatmapMetadata();

        public IBeatmapDifficultyInfo Difficulty => new BeatmapDifficulty
        {
            DrainRate = DrainRate,
            CircleSize = CircleSize,
            ApproachRate = ApproachRate,
            OverallDifficulty = OverallDifficulty,
        };

        IBeatmapSetInfo? IBeatmapInfo.BeatmapSet => BeatmapSet;

        public string MD5Hash => Checksum;

        public IRulesetInfo Ruleset => new RulesetInfo { ID = RulesetID };

        [JsonIgnore]
        public string Hash => throw new NotImplementedException();

        #endregion
    }
}
{'fraction_non_alphanumeric': 0.0943994364212751, 'fraction_numerical': 0.0004696489374192791, 'mean_word_length': 2.094079186342172, 'pattern_counts': {'":': 0, '<': 8, '<?xml version=': 0, '>': 24, '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': '2762950', 'n_tokens_mistral': 2370, 'n_tokens_neox': 2197, 'n_words': 582}