#!/usr/bin/env ruby

require "fileutils"
require "open3"
require "rbconfig"
require "tmpdir"

CHECKER = File.expand_path("check_changed_scenarios.rb", __dir__)
REQUEST_JSON = '{"name":"aws","args":["ec2","describe-vpcs","--region","{region}"],"args_params":{"region":"region"}}'.freeze
ARGS_PARAMS_JSON = '{"region":"region"}'.freeze

def assert(condition, message)
  raise "Assertion failed: #{message}" unless condition
end

def valid_command
  <<~YAML
    scenario:
      id: checker-test
      context:
        base_path:
        host:
      description: checker regression fixture
      name: checker regression fixture
    steps:
      - operation_id: DescribeVpcs
        request_type: cmd_aws
        request: |-
          #{REQUEST_JSON}
        expect: |-
          {"exit_code":0}
        save: null
        max_retries: 0
        delay_after: 0
        continue_on_unexpected: false
        order: 1
  YAML
end

def run_checker(repo, content)
  path = File.join(repo, "scenario_testcases", "case.yaml")
  File.write(path, content)
  stdout, stderr, status = Open3.capture3(
    RbConfig.ruby, "--disable-gems", CHECKER, "--base", "HEAD", "--file", "scenario_testcases/case.yaml",
    chdir: repo
  )
  [status, stdout + stderr]
end

Dir.mktmpdir("scenario-checker-test") do |repo|
  FileUtils.mkdir_p(File.join(repo, "scenario_testcases"))
  assert(system("git", "init", "--quiet", repo), "temporary git repository initializes")
  assert(system("git", "-C", repo, "config", "user.name", "Scenario Checker Test"), "temporary git user name configures")
  assert(system("git", "-C", repo, "config", "user.email", "checker@example.invalid"), "temporary git user email configures")
  assert(system("git", "-C", repo, "commit", "--quiet", "--allow-empty", "-m", "fixture baseline"), "temporary baseline commits")

  status, output = run_checker(repo, valid_command)
  assert(status.success?, "valid command exits zero: #{output}")
  assert(output.include?("未发现静态结构问题。"), "valid command reports no findings")
  assert(output.include?("Static findings: 0."), "valid command reports zero count")

  {
    "request" => valid_command.sub(REQUEST_JSON, "[]"),
    "expect" => valid_command.sub('{"exit_code":0}', "[]"),
    "save" => valid_command.sub("save: null", "save: |-\n      []")
  }.each do |field, content|
    status, output = run_checker(repo, content)
    assert(!status.success?, "#{field} array exits nonzero")
    assert(output.include?("`#{field}` JSON must decode to an object."), "#{field} array has actionable diagnostic")
  end

  status, output = run_checker(repo, valid_command.sub(ARGS_PARAMS_JSON, '{}'))
  assert(!status.success?, "missing args_params binding exits nonzero")
  assert(output.include?("Command placeholder `{region}` is not bound in `args_params`."), "missing binding has actionable diagnostic")

  FileUtils.rm_f(File.join(repo, "scenario_testcases", "case.yaml"))
  stdout, stderr, status = Open3.capture3(
    RbConfig.ruby, "--disable-gems", CHECKER, "--base", "HEAD",
    chdir: repo
  )
  assert(status.success?, "no changed files exits zero: #{stdout}#{stderr}")
  assert(stdout.include?("未发现变更的 scenario YAML"), "no-file case reports empty scope")
end

puts "check_changed_scenarios regression tests: PASS"
