require "vnd.dovecot.testsuite";
require "vnd.dovecot.execute";
require "vnd.dovecot.debug";
require "variables";
require "relational";
require "environment";
require "encoded-character";

test_set "message" text:
From: stephan@example.com
To: pipe@example.net
Subject: Frop!

Frop!
.
;

test_config_set "sieve_execute_bin_dir" "${tst.path}/../bin";
test_config_reload :extension "vnd.dovecot.execute";
test_result_reset;

test "Execute - bare" {
	execute "program";
}

test_result_reset;
test "Execute - i/-" {
	execute :input "FROP" "frame";
}

test_result_reset;
test "Execute - -/o" {
	execute :output "out" "frame";

	if not string "${out}" "FRAMED {  }" {
		test_fail "wrong string returned: ${out}";
	}
}

test_result_reset;
test "Execute - i/o" {
	execute :input "FROP" :output "out" "frame";

	if not string "${out}" "FRAMED { FROP }" {
		test_fail "wrong string returned: ${out}";
	}
}

test_result_reset;
test "Execute - i/o and arguments" {
	execute :input "FROP" :output "out" "frame" ["FRIEP "];

	if not string "${out}" "FRAMED FRIEP { FROP }" {
		test_fail "wrong string returned: ${out}";
	}
}

test_result_reset;
test "Execute - pipe" {
	execute :pipe :output "msg" "cat";

	if not string :contains "${msg}" "Subject: Frop!" {
		test_fail "wrong string returned: ${out}";
	}
}

test_result_reset;
test "Execute - pipe /dev/stdin" {
	execute :pipe :output "msg" "cat-stdin";

	if not string :contains "${msg}" "Subject: Frop!" {
		test_fail "wrong string returned: ${out}";
	}
}

test_result_reset;
test "Execute - env" {
	test_set "envelope.from" "stephan@sub.example.com";
	test_set "envelope.to" "stephan@sub.example.net";
	test_set "envelope.orig_to" "all@sub.example.net";

	execute :output "out" "env" "SENDER";
	if not string :is "${out}" "stephan@sub.example.com" {
		test_fail "wrong SENDER env returned: '${out}'";
	}

	execute :output "out" "env" "RECIPIENT";
	if not string :is "${out}" "stephan@sub.example.net" {
		test_fail "wrong RECIPIENT env returned: '${out}'";
	}

	execute :output "out" "env" "ORIG_RECIPIENT";
	if not string :is "${out}" "all@sub.example.net" {
		test_fail "wrong ORIG_RECIPIENT env returned: '${out}'";
	}

	execute :output "out" "env" "HOST";
	if not environment :is "host" "${out}" {
		test_fail "wrong HOST env returned: '${out}'";
	}

	execute :output "out" "env" "HOME";
	if string :count "eq" "${out}" "0" {
		test_fail "empty HOME env returned";
	}

	execute :output "out" "env" "USER";
	if string :count "eq" "${out}" "0" {
		test_fail "empty USER env returned";
	}
}

test_result_reset;
test "Execute - used as test" {
	if execute :pipe :output "msg" "dog" {
		test_fail "execute action indicated success with invalid program";
	}

	if not execute :pipe :output "msg" "cat" {
		test_fail "execute action indicated failure with valid program";
	}

	if not string :contains "${msg}" "Subject: Frop!" {
		test_fail "wrong string returned: ${out}";
	}
}
	
test_config_set "sieve_execute_input_eol" "crlf";
test_config_reload :extension "vnd.dovecot.execute";
test_result_reset;
set "out" "";

test "Execute - CRLF" {
	execute
		:input "FROP${hex:0A}FRIEP${hex:0a}"
		:output "out"
		"crlf";

	if not string "${out}" "FROP#${hex:0A}FRIEP#${hex:0a}" {
		test_fail "wrong string returned: '${out}'";
	}
}

test_config_set "sieve_execute_input_eol" "lf";
test_config_reload :extension "vnd.dovecot.execute";
test_result_reset;
set "out" "";

test "Execute - LF" {
	execute
		:input "FROP${hex:0D 0A}FRIEP${hex:0d 0a}"
		:output "out"
		"crlf";

	if not string "${out}" "FROP${hex:0A}FRIEP${hex:0a}" {
		test_fail "wrong string returned: '${out}'";
	}
}

set "D" "0123456701234567012345670123456701234567012345670123456701234567";
set "D" "${D}${D}${D}${D}${D}${D}${D}${D}${D}${D}${D}${D}${D}${D}${D}${D}";
set "data" "${D}${D}";

test_config_set "sieve_execute_input_eol" "crlf";
test_config_reload :extension "vnd.dovecot.execute";
test_result_reset;
set "out" "";

test "Execute - big" {
	execute
		:output "out"
		"big";

	if not string "${out}" "${data}" {
		test_fail "wrong string returned: '${out}'";
	}
}
