package linthost

import (
  "encoding/json"
  "testing"
)

// TestParseRulesAcceptsESLintTuplesInStandardInlineConfig verifies tuple support.
//
// Inline lint config now accepts ESLint-style `[severity, options]` tuples
// alongside bare severity literals. The two slots are captured into the
// RuleConfig severity map and the RuleOptionsMap options blob respectively,
// so rule implementations can decode their per-rule option struct from the
// stored JSON.
//
// 1. Build an inline rules map mixing a bare severity and a tuple form.
// 2. Parse it through `ParseRulesWithOptions`.
// 3. Assert severity and options are routed to the correct collection.
//
// @evidence contracts/testing.md#behavioral-verification ParseRulesWithOptions parses one severity-only rule and one severity/options tuple, retaining option object fields and omitting an unnecessary options blob.
// @evidence contracts/testing.md#independent-expectations ESLint-compatible tuple shape independently requires warning severity and the authored importOrder/importOrderSeparation values.
// @evidence contracts/testing.md#distinguishing-cases The severity-only and object-option cases distinguish absence from preservation; ParseRulesPreservesPositionalOptions owns scalar and multiple slots.
// @evidence contracts/testing.md#execution-ownership This discoverable Go entry owns the case described above. An authored bare severity and option tuple reach ParseRulesWithOptions and independent JSON decoding in-process; stored severity and option fields are observed without rule execution or consumer installation.
func TestParseRulesAcceptsESLintTuplesInStandardInlineConfig(t *testing.T) {
  cfg, opts, err := ParseRulesWithOptions(map[string]any{
    "no-var": "error",
    "format/sort-imports": []any{
      "warning",
      map[string]any{
        "importOrder":           []any{"<THIRD_PARTY_MODULES>", "^[./]"},
        "importOrderSeparation": true,
      },
    },
  })
  if err != nil {
    t.Fatalf("ParseRulesWithOptions: %v", err)
  }
  if cfg["no-var"] != SeverityError {
    t.Fatalf("noVar severity: want error, got %v", cfg["no-var"])
  }
  if cfg["format/sort-imports"] != SeverityWarn {
    t.Fatalf("formatSortImports severity: want warning, got %v", cfg["format/sort-imports"])
  }
  if _, exists := opts["no-var"]; exists {
    t.Fatalf("severity-only rule must not have an options blob recorded")
  }
  raw, ok := opts["format/sort-imports"]
  if !ok {
    t.Fatalf("tuple rule must produce an options blob")
  }
  var decoded struct {
    ImportOrder           []string `json:"importOrder"`
    ImportOrderSeparation bool     `json:"importOrderSeparation"`
  }
  if err := json.Unmarshal(raw, &decoded); err != nil {
    t.Fatalf("options blob is not valid JSON: %v", err)
  }
  if len(decoded.ImportOrder) != 2 || decoded.ImportOrder[0] != "<THIRD_PARTY_MODULES>" || decoded.ImportOrder[1] != "^[./]" {
    t.Fatalf("importOrder did not round-trip: %+v", decoded)
  }
  if !decoded.ImportOrderSeparation {
    t.Fatalf("importOrderSeparation did not round-trip")
  }
}
