<commit_before>﻿using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Logging;
using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using Tgstation.Server.Api;
using Tgstation.Server.Api.Models;
using Tgstation.Server.Api.Rights;
using Tgstation.Server.Host.Components;
using Tgstation.Server.Host.Core;
using Tgstation.Server.Host.Models;
using Tgstation.Server.Host.Security;

namespace Tgstation.Server.Host.Controllers
{
	/// <summary>
	/// Controller for managing <see cref="Api.Models.Byond.Version"/>s
	/// </summary>
	[Route(Routes.Byond)]
	public sealed class ByondController : ApiController
	{
		/// <summary>
		/// The <see cref="IInstanceManager"/> for the <see cref="ByondController"/>
		/// </summary>
		readonly IInstanceManager instanceManager;

		/// <summary>
		/// The <see cref="IJobManager"/> for the <see cref="ByondController"/>
		/// </summary>
		readonly IJobManager jobManager;

		/// <summary>
		/// Construct a <see cref="ByondController"/>
		/// </summary>
		/// <param name="databaseContext">The <see cref="IDatabaseContext"/> for the <see cref="ApiController"/></param>
		/// <param name="authenticationContextFactory">The <see cref="IAuthenticationContextFactory"/> for the <see cref="ApiController"/></param>
		/// <param name="instanceManager">The value of <see cref="instanceManager"/></param>
		/// <param name="jobManager">The value of <see cref="jobManager"/></param>
		/// <param name="logger">The <see cref="ILogger"/> for the <see cref="ApiController"/></param>
		public ByondController(IDatabaseContext databaseContext, IAuthenticationContextFactory authenticationContextFactory, IInstanceManager instanceManager, IJobManager jobManager, ILogger<ByondController> logger) : base(databaseContext, authenticationContextFactory, logger, true, true)
		{
			this.instanceManager = instanceManager ?? throw new ArgumentNullException(nameof(instanceManager));
			this.jobManager = jobManager ?? throw new ArgumentNullException(nameof(jobManager));
		}

		/// <summary>
		/// Gets the active <see cref="Api.Models.Byond"/> version.
		/// </summary>
		/// <returns>A <see cref="Task{TResult}"/> resulting in the <see cref="IActionResult"/> for the operation.</returns>
		/// <response code="200">Retrieved version information successfully.</response>
		[HttpGet]
		[TgsAuthorize(ByondRights.ReadActive)]
		[ProducesResponseType(typeof(Api.Models.Byond), 200)]
		public Task<IActionResult> Read() => Task.FromResult<IActionResult>(
			Json(new Api.Models.Byond
			{
				Version = instanceManager.GetInstance(Instance).ByondManager.ActiveVersion
			}));

		/// <summary>
		/// Lists installed <see cref="Api.Models.Byond"/> versions.
		/// </summary>
		/// <returns>A <see cref="Task{TResult}"/> resulting in the <see cref="IActionResult"/> for the operation.</returns>
		/// <response code="200">Retrieved version information successfully.</response>
		[HttpGet(Routes.List)]
		[TgsAuthorize(ByondRights.ListInstalled)]
		[ProducesResponseType(typeof(IEnumerable<Api.Models.Byond>), 200)]
		public Task<IActionResult> List() => Task.FromResult<IActionResult>(
			Json(instanceManager.GetInstance(Instance).ByondManager.InstalledVersions.Select(x => new Api.Models.Byond
			{
				Version = x
			})));

		/// <summary>
		/// Changes the active BYOND version to the one specified in a given <paramref name="model"/>.
		/// </summary>
		/// <param name="model">The <see cref="Api.Models.Byond.Version"/> to switch to.</param>
		/// <param name="cancellationToken">The <see cref="CancellationToken"/> for the operation.</param>
		/// <returns>A <see cref="Task{TResult}"/> resulting in the <see cref="IActionResult"/> for the operation.</returns>
		/// <response code="200">Switched active version successfully.</response>
		/// <response code="202">Created <see cref="Api.Models.Job"/> to install and switch active version successfully.</response>
		[HttpPost]
		[TgsAuthorize(ByondRights.ChangeVersion)]
		[ProducesResponseType(typeof(Api.Models.Byond), 200)]
		[ProducesResponseType(typeof(Api.Models.Byond), 202)]
		public async Task<IActionResult> Update([FromBody] Api.Models.Byond model, CancellationToken cancellationToken)
		{
			if (model == null)
				throw new ArgumentNullException(nameof(model));

			if (model.Version == null)
				return BadRequest(new ErrorMessage { Message = "Missing version!" });

			var byondManager = instanceManager.GetInstance(Instance).ByondManager;

			// remove cruff fields
			var installingVersion = new Version(model.Version.Major, model.Version.Minor);

			var result = new Api.Models.Byond();

			if (byondManager.InstalledVersions.Any(x => x == model.Version))
			{
				Logger.LogInformation("User ID {0} changing instance ID {1} BYOND version to {2}", AuthenticationContext.User.Id, Instance.Id, installingVersion);
				await byondManager.ChangeVersion(model.Version, cancellationToken).ConfigureAwait(false);
			}
			else
			{
				Logger.LogInformation("User ID {0} installing BYOND version to {2} on instance ID {1}", AuthenticationContext.User.Id, Instance.Id, installingVersion);

				// run the install through the job manager
				var job = new Models.Job
				{
					Description = String.Format(CultureInfo.InvariantCulture, "Install BYOND version {0}", installingVersion),
					StartedBy = AuthenticationContext.User,
					CancelRightsType = RightsType.Byond,
					CancelRight = (ulong)ByondRights.CancelInstall,
					Instance = Instance
				};
				await jobManager.RegisterOperation(job, (paramJob, databaseContext, progressHandler, ct) => byondManager.ChangeVersion(installingVersion, ct), cancellationToken).ConfigureAwait(false);
				result.InstallJob = job.ToApi();
			}

			if ((AuthenticationContext.GetRight(RightsType.Byond) & (ulong)ByondRights.ReadActive) != 0)
				result.Version = byondManager.ActiveVersion;
			return result.InstallJob != null ? (IActionResult)Accepted(result) : Json(result);
		}
	}
}
<commit_msg>Reduce code complexity<commit_after>﻿using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Logging;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using Tgstation.Server.Api;
using Tgstation.Server.Api.Models;
using Tgstation.Server.Api.Rights;
using Tgstation.Server.Host.Components;
using Tgstation.Server.Host.Core;
using Tgstation.Server.Host.Models;
using Tgstation.Server.Host.Security;

namespace Tgstation.Server.Host.Controllers
{
	/// <summary>
	/// Controller for managing <see cref="Api.Models.Byond.Version"/>s
	/// </summary>
	[Route(Routes.Byond)]
	public sealed class ByondController : ApiController
	{
		/// <summary>
		/// The <see cref="IInstanceManager"/> for the <see cref="ByondController"/>
		/// </summary>
		readonly IInstanceManager instanceManager;

		/// <summary>
		/// The <see cref="IJobManager"/> for the <see cref="ByondController"/>
		/// </summary>
		readonly IJobManager jobManager;

		/// <summary>
		/// Construct a <see cref="ByondController"/>
		/// </summary>
		/// <param name="databaseContext">The <see cref="IDatabaseContext"/> for the <see cref="ApiController"/></param>
		/// <param name="authenticationContextFactory">The <see cref="IAuthenticationContextFactory"/> for the <see cref="ApiController"/></param>
		/// <param name="instanceManager">The value of <see cref="instanceManager"/></param>
		/// <param name="jobManager">The value of <see cref="jobManager"/></param>
		/// <param name="logger">The <see cref="ILogger"/> for the <see cref="ApiController"/></param>
		public ByondController(IDatabaseContext databaseContext, IAuthenticationContextFactory authenticationContextFactory, IInstanceManager instanceManager, IJobManager jobManager, ILogger<ByondController> logger) : base(databaseContext, authenticationContextFactory, logger, true, true)
		{
			this.instanceManager = instanceManager ?? throw new ArgumentNullException(nameof(instanceManager));
			this.jobManager = jobManager ?? throw new ArgumentNullException(nameof(jobManager));
		}

		/// <summary>
		/// Gets the active <see cref="Api.Models.Byond"/> version.
		/// </summary>
		/// <returns>A <see cref="Task{TResult}"/> resulting in the <see cref="IActionResult"/> for the operation.</returns>
		/// <response code="200">Retrieved version information successfully.</response>
		[HttpGet]
		[TgsAuthorize(ByondRights.ReadActive)]
		[ProducesResponseType(typeof(Api.Models.Byond), 200)]
		public Task<IActionResult> Read() => Task.FromResult<IActionResult>(
			Json(new Api.Models.Byond
			{
				Version = instanceManager.GetInstance(Instance).ByondManager.ActiveVersion
			}));

		/// <summary>
		/// Lists installed <see cref="Api.Models.Byond"/> versions.
		/// </summary>
		/// <returns>A <see cref="Task{TResult}"/> resulting in the <see cref="IActionResult"/> for the operation.</returns>
		/// <response code="200">Retrieved version information successfully.</response>
		[HttpGet(Routes.List)]
		[TgsAuthorize(ByondRights.ListInstalled)]
		[ProducesResponseType(typeof(IEnumerable<Api.Models.Byond>), 200)]
		public Task<IActionResult> List() => Task.FromResult<IActionResult>(
			Json(instanceManager.GetInstance(Instance).ByondManager.InstalledVersions.Select(x => new Api.Models.Byond
			{
				Version = x
			})));

		/// <summary>
		/// Changes the active BYOND version to the one specified in a given <paramref name="model"/>.
		/// </summary>
		/// <param name="model">The <see cref="Api.Models.Byond.Version"/> to switch to.</param>
		/// <param name="cancellationToken">The <see cref="CancellationToken"/> for the operation.</param>
		/// <returns>A <see cref="Task{TResult}"/> resulting in the <see cref="IActionResult"/> for the operation.</returns>
		/// <response code="200">Switched active version successfully.</response>
		/// <response code="202">Created <see cref="Api.Models.Job"/> to install and switch active version successfully.</response>
		[HttpPost]
		[TgsAuthorize(ByondRights.ChangeVersion)]
		[ProducesResponseType(typeof(Api.Models.Byond), 200)]
		[ProducesResponseType(typeof(Api.Models.Byond), 202)]
		public async Task<IActionResult> Update([FromBody] Api.Models.Byond model, CancellationToken cancellationToken)
		{
			if (model == null)
				throw new ArgumentNullException(nameof(model));

			if (model.Version == null)
				return BadRequest(new ErrorMessage { Message = "Missing version!" });

			var byondManager = instanceManager.GetInstance(Instance).ByondManager;

			// remove cruff fields
			var installingVersion = new Version(model.Version.Major, model.Version.Minor);

			var result = new Api.Models.Byond();

			if (byondManager.InstalledVersions.Any(x => x == model.Version))
			{
				Logger.LogInformation("User ID {0} changing instance ID {1} BYOND version to {2}", AuthenticationContext.User.Id, Instance.Id, installingVersion);
				await byondManager.ChangeVersion(model.Version, cancellationToken).ConfigureAwait(false);
			}
			else
			{
				Logger.LogInformation("User ID {0} installing BYOND version to {2} on instance ID {1}", AuthenticationContext.User.Id, Instance.Id, installingVersion);

				// run the install through the job manager
				var job = new Models.Job
				{
					Description = $"Install BYOND version {installingVersion}",
					StartedBy = AuthenticationContext.User,
					CancelRightsType = RightsType.Byond,
					CancelRight = (ulong)ByondRights.CancelInstall,
					Instance = Instance
				};
				await jobManager.RegisterOperation(job, (paramJob, databaseContext, progressHandler, ct) => byondManager.ChangeVersion(installingVersion, ct), cancellationToken).ConfigureAwait(false);
				result.InstallJob = job.ToApi();
			}

			if ((AuthenticationContext.GetRight(RightsType.Byond) & (ulong)ByondRights.ReadActive) != 0)
				result.Version = byondManager.ActiveVersion;
			return result.InstallJob != null ? (IActionResult)Accepted(result) : Json(result);
		}
	}
}

{'fraction_non_alphanumeric': 0.1412679826028772, 'fraction_numerical': 0.005269320843091335, 'mean_word_length': 4.759633911368016, 'pattern_counts': {'":': 0, '<': 153, '<?xml version=': 0, '>': 163, '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': '6740356', 'n_tokens_mistral': 3819, 'n_tokens_neox': 3445, 'n_words': 788}