// Kyoo - A portable and vast media library solution.
// Copyright (c) Kyoo.
//
// See AUTHORS.md and LICENSE file in the project root for full license information.
//
// Kyoo is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// any later version.
//
// Kyoo is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Kyoo. If not, see .
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using JetBrains.Annotations;
using Kyoo.Abstractions.Models;
using Kyoo.Abstractions.Models.Exceptions;
namespace Kyoo.Abstractions.Controllers
{
///
/// A common interface that tasks should implement.
///
public interface ITask
{
///
/// The list of parameters
///
///
/// All parameters that this task as. Every one of them will be given to the run function with a value.
///
public TaskParameters GetParameters();
///
/// Start this task.
///
///
/// The list of parameters.
///
///
/// The progress reporter. Used to inform the sender the percentage of completion of this task
/// .
/// A token to request the task's cancellation.
/// If this task is not cancelled quickly, it might be killed by the runner.
///
///
/// An exception meaning that the task has failed for handled reasons like invalid arguments,
/// invalid environment, missing plugins or failures not related to a default in the code.
/// This exception allow the task to display a failure message to the end user while others exceptions
/// will be displayed as unhandled exceptions and display a stack trace.
///
/// A representing the asynchronous operation.
public Task Run([NotNull] TaskParameters arguments,
[NotNull] IProgress progress,
CancellationToken cancellationToken);
}
///
/// A single task parameter. This struct contains metadata to display and utility functions to get them in the task.
///
/// This struct will be used to generate the swagger documentation of the task.
public record TaskParameter
{
///
/// The name of this parameter.
///
public string Name { get; init; }
///
/// The description of this parameter.
///
public string Description { get; init; }
///
/// The type of this parameter.
///
public Type Type { get; init; }
///
/// Is this parameter required or can it be ignored?
///
public bool IsRequired { get; init; }
///
/// The default value of this object.
///
public object DefaultValue { get; init; }
///
/// The value of the parameter.
///
private object _Value { get; init; }
///
/// Create a new task parameter.
///
/// The name of the parameter
/// The description of the parameter
/// The type of the parameter.
/// A new task parameter.
public static TaskParameter Create(string name, string description)
{
return new TaskParameter
{
Name = name,
Description = description,
Type = typeof(T)
};
}
///
/// Create a new required task parameter.
///
/// The name of the parameter
/// The description of the parameter
/// The type of the parameter.
/// A new task parameter.
public static TaskParameter CreateRequired(string name, string description)
{
return new TaskParameter
{
Name = name,
Description = description,
Type = typeof(T),
IsRequired = true
};
}
///
/// Create a parameter's value to give to a task.
///
/// The name of the parameter
/// The value of the parameter. It's type will be used as parameter's type.
/// The type of the parameter
/// A TaskParameter that can be used as value.
public static TaskParameter CreateValue(string name, T value)
{
return new()
{
Name = name,
Type = typeof(T),
_Value = value
};
}
///
/// Create a parameter's value for the current parameter.
///
/// The value to use
/// A new parameter's value for this current parameter
public TaskParameter CreateValue(object value)
{
return this with { _Value = value };
}
///
/// Get the value of this parameter. If the value is of the wrong type, it will be converted.
///
/// The type of this parameter
/// The value of this parameter.
public T As()
{
if (typeof(T) == typeof(object))
return (T)_Value;
if (_Value is IResource resource)
{
if (typeof(T) == typeof(string))
return (T)(object)resource.Slug;
if (typeof(T) == typeof(int))
return (T)(object)resource.ID;
}
return (T)Convert.ChangeType(_Value, typeof(T));
}
}
///
/// A parameters container implementing an indexer to allow simple usage of parameters.
///
public class TaskParameters : List
{
///
/// An indexer that return the parameter with the specified name.
///
/// The name of the task (case sensitive)
public TaskParameter this[string name] => this.FirstOrDefault(x => x.Name == name);
///
/// Create a new, empty,
///
public TaskParameters() { }
///
/// Create a with an initial parameters content.
///
/// The list of parameters
public TaskParameters(IEnumerable parameters)
{
AddRange(parameters);
}
}
}