#!/usr/bin/perl
#
# SPDX-FileCopyrightText: Peter Pentchev <roam@ringlet.net>
# SPDX-License-Identifier: BSD-2-Clause

use v5.010;
use strict;
use warnings;

use JSON::XS qw(decode_json);
use Test::More;
use Test::Command;

use lib 't/lib';
use Test::FeatureCheck qw(
	env_init
	get_error_output get_ok_output
	test_fcheck_init
);

my %alt_ops = (
	{{#each simple.synonyms}}
	'{{this.name}}' => '{{this.sym}}',
	{{/each}}
);

my @tests = (
	{{#each simple.compare}}
	['{{this.name}} {{this.op}} {{this.version}}', {{perlbool this.result}}],
	{{/each}}
);

my %c = env_init;

plan tests => 2 + 6 * scalar @tests;

test_fcheck_init \%c;

subtest 'Check for simple feature support' => sub {
	my @lines = get_ok_output([$c{prog}, '--features'], 'get features');
	is scalar @lines, 1, 'list features output a single line';
	BAIL_OUT('No "Features: " on the features line') unless
	    $lines[0] =~ /^ Features: \s (?<features> .* ) $/x;
	my @words = split /\s+/, $+{features};
	my %names = map { split /[:\/=]/, $_, 2 } @words;
	BAIL_OUT('No "simple" in the features list') unless
	    defined $names{'simple'};
	BAIL_OUT('Only know how to test the "simple" feature version 1.x') unless
	    $names{'simple'} =~ m{^ 1 (?: \..* )? $ }x;
};

for my $t (@tests) {
	my ($test, $exp) = @{$t};
	my @words = split /\s+/, $test;
	die "Internal error: test '$test': how many words?\n"
	    unless @words == 3;

	my $alt_op = $alt_ops{$words[1]};
	die "Internal error: no alt op for '$words[1]'\n"
	    unless defined $alt_op;
	my @alt_words = ($words[0], $alt_op, $words[2]);

	subtest "$test" => sub {
		my $cmd = [$c{prog}, $c{fcheck}, $test];
		my @lines;
		if ($exp) {
			@lines = get_ok_output($cmd, $test);
		} else {
			@lines = get_error_output($cmd, $test);
		}
		is scalar @lines, 0, "'$test' output nothing";
	};

	subtest "$test" => sub {
		my $cmd = [$c{prog}, $c{fcheck}, join ' ', @alt_words];
		my @lines;
		if ($exp) {
			@lines = get_ok_output($cmd, $test);
		} else {
			@lines = get_error_output($cmd, $test);
		}
		is scalar @lines, 0, "'$test' output nothing";
	};

	subtest "$test" => sub {
		my $cmd = [$c{prog}, $c{fcheck}, @words];
		my @lines;
		if ($exp) {
			@lines = get_ok_output($cmd, $test);
		} else {
			@lines = get_error_output($cmd, $test);
		}
		is scalar @lines, 0, "'$test' output nothing";
	};

	subtest "$test" => sub {
		my $cmd = [$c{prog}, $c{fcheck}, @alt_words];
		my @lines;
		if ($exp) {
			@lines = get_ok_output($cmd, $test);
		} else {
			@lines = get_error_output($cmd, $test);
		}
		is scalar @lines, 0, "'$test' output nothing";
	};

	subtest "$test" => sub {
		my $cmd = [$c{prog}, $c{fcheck},
		    $words[0], "$words[1] $words[2]"];
		my @lines;
		if ($exp) {
			@lines = get_ok_output($cmd, $test);
		} else {
			@lines = get_error_output($cmd, $test);
		}
		is scalar @lines, 0, "'$test' output nothing";
	};

	subtest "$test" => sub {
		my $cmd = [$c{prog}, $c{fcheck},
		    $alt_words[0], "$alt_words[1] $alt_words[2]"];
		my @lines;
		if ($exp) {
			@lines = get_ok_output($cmd, $test);
		} else {
			@lines = get_error_output($cmd, $test);
		}
		is scalar @lines, 0, "'$test' output nothing";
	};
}
