//! Integration tests for governor-core

use governor_core::domain::commit::{Commit, CommitHistory, CommitType};
use governor_core::domain::dependency::{DependencyGraph, WorkspaceDependency};
use governor_core::domain::version::{BumpType, SemanticVersion};
use semver::Version;

#[test]
fn test_commit_to_version_workflow() {
    let commits = vec![
        Commit::new(
            "1".to_string(),
            "feat: new api".to_string(),
            "A".to_string(),
            "a@a.com".to_string(),
            chrono::Utc::now(),
        ),
        Commit::new(
            "2".to_string(),
            "fix: bug fix".to_string(),
            "A".to_string(),
            "a@a.com".to_string(),
            chrono::Utc::now(),
        ),
    ];

    let history = CommitHistory::new(commits);
    let feat_commits = history.by_type(CommitType::Feat);
    let fix_commits = history.by_type(CommitType::Fix);

    assert_eq!(feat_commits.len(), 1);
    assert_eq!(fix_commits.len(), 1);
}

#[test]
fn test_version_bump_workflow() {
    let v = SemanticVersion::from(Version::new(1, 0, 0));

    // Patch bump
    let v_patch = BumpType::Patch.apply_to(&v);
    assert_eq!(v_patch.to_string(), "1.0.1");

    // Minor bump
    let v_minor = BumpType::Minor.apply_to(&v);
    assert_eq!(v_minor.to_string(), "1.1.0");

    // Major bump
    let v_major = BumpType::Major.apply_to(&v);
    assert_eq!(v_major.to_string(), "2.0.0");
}

#[test]
fn test_dependency_graph_with_versions() {
    let mut graph = DependencyGraph::new();

    // Create a dependency chain: c -> b -> a
    graph.add(WorkspaceDependency::new(
        "pkg-c".to_string(),
        "pkg-b".to_string(),
        "workspace".to_string(),
    ));
    graph.add(WorkspaceDependency::new(
        "pkg-b".to_string(),
        "pkg-a".to_string(),
        "workspace".to_string(),
    ));

    let order = graph.publish_order().unwrap();
    assert_eq!(order[0], "pkg-a");
    assert_eq!(order[1], "pkg-b");
    assert_eq!(order[2], "pkg-c");
}

#[test]
fn test_conventional_commit_with_scope_and_breaking() {
    let commit = Commit::new(
        "abc123".to_string(),
        "feat(api)!: breaking change".to_string(),
        "Author".to_string(),
        "author@example.com".to_string(),
        chrono::Utc::now(),
    );

    assert_eq!(commit.commit_type(), Some(CommitType::Feat));
    assert_eq!(commit.scope, Some("api".to_string()));
    assert!(commit.breaking);
}

#[test]
fn test_prerelease_version_parsing() {
    let v = SemanticVersion::parse("1.0.0-beta.1").unwrap();
    assert!(v.is_prerelease);
    assert_eq!(v.prerelease_type, Some("beta".to_string()));
    assert_eq!(v.to_string(), "1.0.0-beta.1");
}

#[test]
fn test_version_roundtrip() {
    let original = "2.4.6-rc.1+build.123";
    let parsed = SemanticVersion::parse(original).unwrap();
    assert_eq!(parsed.to_string(), original);
}
