package linthost

import (
  "os"
  "path/filepath"
  "strings"
  "testing"
)

// TestCommandFormatRestoresSwitchIndentFromFlat verifies the `ttsc format`
// cascade re-indents switch case labels, their bodies, and the case-body
// block braces from a fully flattened source. ttsc-only self-check against
// the canonical answer key; Prettier is not used.
//
// A `case`/`default` label is not a statement. A formatter that moved only
// body statements could leave labels and case-block braces at column 0;
// full-file equality distinguishes that incomplete transformation.
//
//  1. Flatten a switch canonical (block-bodied cases) to column 0.
//  2. Run `ttsc format`.
//  3. Assert it converges and restores the canonical exactly.
//
// @evidence contracts/testing.md#behavioral-verification Strips the leading whitespace from every line of an authored function holding a `switch` with a block-bodied `case 1` and `default`, runs the in-process `format` command (semi false), and requires exit 0 without a did-not-converge message and the file equal to the authored indented text.
// @evidence contracts/testing.md#independent-expectations The expected text is an authored canonical literal; the flat input is derived from it by removing leading whitespace, which leaves the syntax tree identical.
// @evidence contracts/testing.md#distinguishing-cases One input that must change: case and default labels, their bodies and the case-block braces all start at column 0; a cascade that re-indented only statements would leave labels and braces at column 0.
// @evidence contracts/testing.md#execution-ownership In-process Go unit: calls run with the format subcommand on a temp-dir project and JSON config; no child process, built binary or installed consumer.
func TestCommandFormatRestoresSwitchIndentFromFlat(t *testing.T) {
  canonical := "function h(x) {\n" +
    "  switch (x) {\n" +
    "    case 1: {\n" +
    "      doA()\n" +
    "      break\n" +
    "    }\n" +
    "    default: {\n" +
    "      doB()\n" +
    "    }\n" +
    "  }\n" +
    "}\n"
  var flat strings.Builder
  for _, line := range strings.Split(canonical, "\n") {
    flat.WriteString(strings.TrimLeft(line, " \t"))
    flat.WriteString("\n")
  }
  source := strings.TrimSuffix(flat.String(), "\n")

  root := seedLintProject(t, source)
  seedLintConfig(t, root, map[string]any{"format": map[string]any{"semi": false}})
  main := filepath.Join(root, "src", "main.ts")

  code, _, stderr := captureCommandOutput(t, func() int {
    return run([]string{"format", "--cwd", root, "--plugins-json", lintManifest(t)})
  })
  if code != 0 || strings.Contains(stderr, "did not converge") {
    t.Fatalf("format did not converge: code=%d stderr=%q", code, stderr)
  }
  got, err := os.ReadFile(main)
  if err != nil {
    t.Fatalf("ReadFile: %v", err)
  }
  if string(got) != canonical {
    t.Fatalf("switch indent not restored:\ngot  %q\nwant %q", string(got), canonical)
  }
}
