using System.ComponentModel.DataAnnotations;
using MarketAlly.GitCommitEditor.Resources;
namespace MarketAlly.GitCommitEditor.Options;
public sealed class GitImproverOptions : IValidatableObject
{
///
/// Root directory to scan for git repositories
///
public string WorkspaceRoot { get; set; } = string.Empty;
///
/// Path to persist state between sessions
///
public string StateFilePath { get; set; } = "git-improver-state.json";
///
/// Rules for analyzing commit message quality
///
public CommitMessageRules Rules { get; set; } = new();
///
/// AI configuration for generating suggestions
///
public AiOptions Ai { get; set; } = new();
///
/// Maximum number of commits to analyze per repo
///
public int MaxCommitsPerRepo { get; set; } = 100;
///
/// Only analyze commits newer than this date
///
public DateTimeOffset? AnalyzeSince { get; set; }
///
/// Skip commits by these authors (useful for excluding bots)
///
public string[] ExcludedAuthors { get; set; } = [];
public IEnumerable Validate(ValidationContext validationContext)
{
if (string.IsNullOrWhiteSpace(WorkspaceRoot))
{
yield return new ValidationResult(
Str.Validation_WorkspaceRequired,
[nameof(WorkspaceRoot)]);
}
else if (!Directory.Exists(WorkspaceRoot))
{
yield return new ValidationResult(
Str.Validation_WorkspaceNotFound(WorkspaceRoot),
[nameof(WorkspaceRoot)]);
}
if (MaxCommitsPerRepo <= 0)
{
yield return new ValidationResult(
Str.Validation_MaxCommitsPositive,
[nameof(MaxCommitsPerRepo)]);
}
if (Rules == null)
{
yield return new ValidationResult(
Str.Validation_RulesNull,
[nameof(Rules)]);
}
if (Ai == null)
{
yield return new ValidationResult(
Str.Validation_AiOptionsNull,
[nameof(Ai)]);
}
}
public void ValidateAndThrow()
{
var results = Validate(new ValidationContext(this)).ToList();
if (results.Count > 0)
{
var messages = string.Join("; ", results.Select(r => r.ErrorMessage));
throw new ValidationException(Str.Validation_InvalidOptions(messages));
}
}
}