package roadmapsync

import (
	"errors"
	"testing"
)

const milestonePath = "agent-roadmap/phase/agent-ops-mcp-control-plane/milestones/milestone-work-item-creation-sync.md"

func TestParseMilestoneIdentityHeadingBlock(t *testing.T) {
	md := `# Milestone

본문 텍스트.

## Provider identity

- provider: plane
- tenant: general
- project: NOMAD
- work item id: ` + "`NOMAD-13`" + `

## 완료 리뷰
- provider: ignored-after-block
`
	got, err := ParseMilestoneIdentity(milestonePath, md)
	if err != nil {
		t.Fatalf("unexpected error: %v", err)
	}
	if got.Provider != "plane" || got.WorkItemID != "NOMAD-13" {
		t.Errorf("identity = %+v", got)
	}
	if got.Tenant != "general" || got.Project != "NOMAD" {
		t.Errorf("tenant/project not parsed: %+v", got)
	}
	if got.RoadmapMilestonePath != milestonePath {
		t.Errorf("path = %q", got.RoadmapMilestonePath)
	}
	if got.Shape != ShapeMilestone {
		t.Errorf("shape = %q", got.Shape)
	}
}

func TestParseMilestoneIdentityBulletBlock(t *testing.T) {
	md := `# Milestone

- Provider identity:
  - provider: plane
  - work_item_id: NOMAD-42
`
	got, err := ParseMilestoneIdentity(milestonePath, md)
	if err != nil {
		t.Fatalf("unexpected error: %v", err)
	}
	if got.Provider != "plane" || got.WorkItemID != "NOMAD-42" {
		t.Errorf("identity = %+v", got)
	}
}

func TestParseMilestoneIdentityTaskShape(t *testing.T) {
	md := `## Provider identity
- provider: plane
- work item id: NOMAD-50
- parent work item id: NOMAD-13
`
	got, err := ParseMilestoneIdentity(milestonePath, md)
	if err != nil {
		t.Fatalf("unexpected error: %v", err)
	}
	if got.Shape != ShapeTask || got.ParentWorkItemID != "NOMAD-13" {
		t.Errorf("expected task shape with parent: %+v", got)
	}
}

func TestParseMilestoneIdentityBulletBoundaryRejectsSiblings(t *testing.T) {
	// "- Provider identity:" has no nested child fields; the later top-level
	// sibling bullets must not be absorbed as identity fields.
	md := `# Milestone

- Provider identity:
- provider: plane
- work item id: NOMAD-13
`
	_, err := ParseMilestoneIdentity(milestonePath, md)
	if !errors.Is(err, ErrNoProviderIdentity) {
		t.Fatalf("err = %v, want ErrNoProviderIdentity", err)
	}
}

func TestParseMilestoneIdentityBulletBoundaryClosesOnOutdent(t *testing.T) {
	// Nested children supply a partial identity, then an outdent sibling tries
	// to add work item id. The outdent closes the block, so the identity stays
	// incomplete and is rejected.
	md := `# Milestone

- Provider identity:
  - provider: plane
- work item id: NOMAD-13
`
	_, err := ParseMilestoneIdentity(milestonePath, md)
	if !errors.Is(err, ErrNoProviderIdentity) {
		t.Fatalf("err = %v, want ErrNoProviderIdentity", err)
	}
}

func TestParseMilestoneIdentityBulletBoundaryClosesOnBlankLine(t *testing.T) {
	md := `# Milestone

- Provider identity:
  - provider: plane

  - work item id: NOMAD-13
`
	_, err := ParseMilestoneIdentity(milestonePath, md)
	if !errors.Is(err, ErrNoProviderIdentity) {
		t.Fatalf("err = %v, want ErrNoProviderIdentity (blank line closes block)", err)
	}
}

func TestParseMilestoneIdentityNoBlock(t *testing.T) {
	md := `# Milestone

provider 정보가 본문에 없다.

## 완료 리뷰
- 상태: 없음
`
	_, err := ParseMilestoneIdentity(milestonePath, md)
	if !errors.Is(err, ErrNoProviderIdentity) {
		t.Fatalf("err = %v, want ErrNoProviderIdentity", err)
	}
}

func TestParseMilestoneIdentityIncompleteBlock(t *testing.T) {
	// Block present but missing work item id: must not silently succeed.
	md := `## Provider identity
- provider: plane
- project: NOMAD
`
	_, err := ParseMilestoneIdentity(milestonePath, md)
	if !errors.Is(err, ErrNoProviderIdentity) {
		t.Fatalf("err = %v, want ErrNoProviderIdentity", err)
	}
}

func TestParseMilestoneIdentityEmptyPath(t *testing.T) {
	if _, err := ParseMilestoneIdentity("  ", "## Provider identity\n- provider: plane\n- work item id: X\n"); !errors.Is(err, ErrInvalidIdentity) {
		t.Fatalf("err = %v, want ErrInvalidIdentity", err)
	}
}
