/*
 * Copyright (c) 2005 Sendmail, Inc. and its suppliers.
 *	All rights reserved.
 *
 * By using this file, you agree to the terms and conditions set
 * forth in the LICENSE file which can be found at the top level of
 * the sendmail distribution.
 */

#include "sm/generic.h"
SM_RCSID("@(#)$Id: t-hdrmodh-0.c,v 1.2 2005/11/19 01:52:55 ca Exp $")
#include "sm/error.h"
#include "sm/assert.h"
#include "sm/hdrmod.h"
#include "sm/io.h"
#include "sm/sysexits.h"
#include "sm/test.h"

static int Verbose = 0;

static void
testhdrmod0(void)
{
	sm_ret_T ret;
	sm_hdrmodhd_P sm_hdrmodhd;
	sm_hdrmod_P sm_hdrmod;

	sm_hdrmodhd = NULL;
	ret = sm_hdrmod_new(&sm_hdrmodhd, true, &sm_hdrmod);
	SM_TEST(sm_is_success(ret));
	SM_TEST(!HDRMODL_EMPTY(sm_hdrmodhd));

	ret = sm_hdrmod_rm(&sm_hdrmodhd);
	SM_TEST(sm_is_success(ret));
	SM_TEST(NULL == sm_hdrmodhd);

	ret = sm_hdrmod_new(&sm_hdrmodhd, true, &sm_hdrmod);
	SM_TEST(sm_is_success(ret));
	ret = sm_hdrmodl_free(&sm_hdrmodhd);
	SM_TEST(sm_is_success(ret));
	SM_TEST(NULL == sm_hdrmodhd);
}

static void
chkhdrmod(sm_hdrmod_P sm_hdrmod, sm_hm_type_T type, uint pos, const char *hdr)
{
	SM_TEST(NULL != sm_hdrmod);
	SM_TEST(type == sm_hdrmod->sm_hm_type);
	SM_TEST(pos == sm_hdrmod->sm_hm_pos);
	if (hdr == NULL)
		return;
	SM_TEST(sm_hdrmod->sm_hm_hdr != NULL);
	SM_TEST(0 == strncmp((const char *)sm_cstr_data(sm_hdrmod->sm_hm_hdr),
			hdr, strlen(hdr)));
}

static void
testhdrmodins(void)
{
	sm_ret_T ret;
	sm_hdrmodhd_P sm_hdrmodhd;
	sm_hdrmod_P sm_hdrmod;

#define HDR1	"first"
#define HDR2	"second"
#define HDR2_I1	"second: insert1"
#define HDR2_I2	"second: insert2"
#define HDR3	"third"
#define HDR4	"forth"

	sm_hdrmodhd = NULL;

	/* FIRST */
	ret = sm_hdrmod_new(&sm_hdrmodhd, true, &sm_hdrmod);
	SM_TEST(sm_is_success(ret));
	SM_TEST(!HDRMODL_EMPTY(sm_hdrmodhd));

	sm_hdrmod->sm_hm_type = SM_HM_TYPE_PREPEND;
	sm_hdrmod->sm_hm_pos = 0;
	sm_hdrmod->sm_hm_hdr = sm_cstr_scpyn((const uchar *) HDR1,
					strlen(HDR1));
	SM_TEST(sm_hdrmod->sm_hm_hdr != NULL);

	sm_hdrmod = HDRMODL_FIRST(sm_hdrmodhd);
	chkhdrmod(sm_hdrmod, SM_HM_TYPE_PREPEND , 0, HDR1);

	sm_hdrmod = HDRMODL_NEXT(sm_hdrmod);
	SM_TEST(sm_hdrmod == HDRMODL_END(sm_hdrmodhd));

	/* SECOND */
	ret = sm_hdrmod_new(&sm_hdrmodhd, false, &sm_hdrmod);
	SM_TEST(sm_is_success(ret));
	SM_TEST(!HDRMODL_EMPTY(sm_hdrmodhd));

	sm_hdrmod->sm_hm_type = SM_HM_TYPE_PREPEND;
	sm_hdrmod->sm_hm_pos = 0;
	sm_hdrmod->sm_hm_hdr = sm_cstr_scpyn((const uchar *) HDR2,
					strlen(HDR2));
	SM_TEST(sm_hdrmod->sm_hm_hdr != NULL);
	ret = sm_hdrmod_insert(sm_hdrmodhd, sm_hdrmod);
	SM_TEST(sm_is_success(ret));

	sm_hdrmod = HDRMODL_FIRST(sm_hdrmodhd);
	chkhdrmod(sm_hdrmod, SM_HM_TYPE_PREPEND , 0, HDR1);

	sm_hdrmod = HDRMODL_NEXT(sm_hdrmod);
	chkhdrmod(sm_hdrmod, SM_HM_TYPE_PREPEND , 0, HDR2);

	sm_hdrmod = HDRMODL_NEXT(sm_hdrmod);
	SM_TEST(sm_hdrmod == HDRMODL_END(sm_hdrmodhd));

	/* THIRD */
	ret = sm_hdrmod_new(&sm_hdrmodhd, false, &sm_hdrmod);
	SM_TEST(sm_is_success(ret));
	SM_TEST(!HDRMODL_EMPTY(sm_hdrmodhd));

	sm_hdrmod->sm_hm_type = SM_HM_TYPE_APPEND;
	sm_hdrmod->sm_hm_pos = 0;
	sm_hdrmod->sm_hm_hdr = sm_cstr_scpyn((const uchar *) HDR3,
					strlen(HDR3));
	SM_TEST(sm_hdrmod->sm_hm_hdr != NULL);
	ret = sm_hdrmod_insert(sm_hdrmodhd, sm_hdrmod);
	SM_TEST(sm_is_success(ret));

	sm_hdrmod = HDRMODL_FIRST(sm_hdrmodhd);
	chkhdrmod(sm_hdrmod, SM_HM_TYPE_PREPEND , 0, HDR1);

	sm_hdrmod = HDRMODL_NEXT(sm_hdrmod);
	chkhdrmod(sm_hdrmod, SM_HM_TYPE_PREPEND , 0, HDR2);

	sm_hdrmod = HDRMODL_NEXT(sm_hdrmod);
	chkhdrmod(sm_hdrmod, SM_HM_TYPE_APPEND, 0, HDR3);

	sm_hdrmod = HDRMODL_NEXT(sm_hdrmod);
	SM_TEST(sm_hdrmod == HDRMODL_END(sm_hdrmodhd));

	/* FOURTH */
	ret = sm_hdrmod_new(&sm_hdrmodhd, false, &sm_hdrmod);
	SM_TEST(sm_is_success(ret));
	SM_TEST(!HDRMODL_EMPTY(sm_hdrmodhd));

	sm_hdrmod->sm_hm_type = SM_HM_TYPE_APPEND;
	sm_hdrmod->sm_hm_pos = 0;
	sm_hdrmod->sm_hm_hdr = sm_cstr_scpyn((const uchar *) HDR4,
					strlen(HDR4));
	SM_TEST(sm_hdrmod->sm_hm_hdr != NULL);
	ret = sm_hdrmod_insert(sm_hdrmodhd, sm_hdrmod);
	SM_TEST(sm_is_success(ret));

	sm_hdrmod = HDRMODL_FIRST(sm_hdrmodhd);
	chkhdrmod(sm_hdrmod, SM_HM_TYPE_PREPEND , 0, HDR1);

	sm_hdrmod = HDRMODL_NEXT(sm_hdrmod);
	chkhdrmod(sm_hdrmod, SM_HM_TYPE_PREPEND , 0, HDR2);

	sm_hdrmod = HDRMODL_NEXT(sm_hdrmod);
	chkhdrmod(sm_hdrmod, SM_HM_TYPE_APPEND, 0, HDR3);

	sm_hdrmod = HDRMODL_NEXT(sm_hdrmod);
	chkhdrmod(sm_hdrmod, SM_HM_TYPE_APPEND, 0, HDR4);

	sm_hdrmod = HDRMODL_NEXT(sm_hdrmod);
	SM_TEST(sm_hdrmod == HDRMODL_END(sm_hdrmodhd));

	/* FIFTH */
	ret = sm_hdrmod_new(&sm_hdrmodhd, false, &sm_hdrmod);
	SM_TEST(sm_is_success(ret));
	SM_TEST(!HDRMODL_EMPTY(sm_hdrmodhd));

	sm_hdrmod->sm_hm_type = SM_HM_TYPE_REMOVE;
	sm_hdrmod->sm_hm_pos = 3;
	sm_hdrmod->sm_hm_hdr = sm_cstr_scpyn((const uchar *) HDR4,
					strlen(HDR4));
	SM_TEST(sm_hdrmod->sm_hm_hdr != NULL);
	ret = sm_hdrmod_insert(sm_hdrmodhd, sm_hdrmod);
	SM_TEST(sm_is_success(ret));

	sm_hdrmod = HDRMODL_FIRST(sm_hdrmodhd);
	chkhdrmod(sm_hdrmod, SM_HM_TYPE_PREPEND , 0, HDR1);

	sm_hdrmod = HDRMODL_NEXT(sm_hdrmod);
	chkhdrmod(sm_hdrmod, SM_HM_TYPE_PREPEND , 0, HDR2);

	sm_hdrmod = HDRMODL_NEXT(sm_hdrmod);
	chkhdrmod(sm_hdrmod, SM_HM_TYPE_REMOVE , 3, NULL);

	sm_hdrmod = HDRMODL_NEXT(sm_hdrmod);
	chkhdrmod(sm_hdrmod, SM_HM_TYPE_APPEND, 0, HDR3);

	sm_hdrmod = HDRMODL_NEXT(sm_hdrmod);
	chkhdrmod(sm_hdrmod, SM_HM_TYPE_APPEND, 0, HDR4);

	sm_hdrmod = HDRMODL_NEXT(sm_hdrmod);
	SM_TEST(sm_hdrmod == HDRMODL_END(sm_hdrmodhd));


	/* insert 2 */
	ret = sm_hdrmod_new(&sm_hdrmodhd, false, &sm_hdrmod);
	SM_TEST(sm_is_success(ret));
	SM_TEST(!HDRMODL_EMPTY(sm_hdrmodhd));

	sm_hdrmod->sm_hm_type = SM_HM_TYPE_INSERT;
	sm_hdrmod->sm_hm_pos = 2;
	sm_hdrmod->sm_hm_hdr = sm_cstr_scpyn((const uchar *) HDR2_I2,
					strlen(HDR2_I2));
	SM_TEST(sm_hdrmod->sm_hm_hdr != NULL);
	ret = sm_hdrmod_insert(sm_hdrmodhd, sm_hdrmod);
	SM_TEST(sm_is_success(ret));

	sm_hdrmod = HDRMODL_FIRST(sm_hdrmodhd);
	chkhdrmod(sm_hdrmod, SM_HM_TYPE_PREPEND , 0, HDR1);

	sm_hdrmod = HDRMODL_NEXT(sm_hdrmod);
	chkhdrmod(sm_hdrmod, SM_HM_TYPE_PREPEND , 0, HDR2);

	sm_hdrmod = HDRMODL_NEXT(sm_hdrmod);
	chkhdrmod(sm_hdrmod, SM_HM_TYPE_INSERT, 2, HDR2_I2);

	sm_hdrmod = HDRMODL_NEXT(sm_hdrmod);
	chkhdrmod(sm_hdrmod, SM_HM_TYPE_REMOVE , 3, NULL);

	sm_hdrmod = HDRMODL_NEXT(sm_hdrmod);
	chkhdrmod(sm_hdrmod, SM_HM_TYPE_APPEND, 0, HDR3);

	sm_hdrmod = HDRMODL_NEXT(sm_hdrmod);
	chkhdrmod(sm_hdrmod, SM_HM_TYPE_APPEND, 0, HDR4);

	sm_hdrmod = HDRMODL_NEXT(sm_hdrmod);
	SM_TEST(sm_hdrmod == HDRMODL_END(sm_hdrmodhd));

	/* insert 1 */
	ret = sm_hdrmod_new(&sm_hdrmodhd, false, &sm_hdrmod);
	SM_TEST(sm_is_success(ret));
	SM_TEST(!HDRMODL_EMPTY(sm_hdrmodhd));

	sm_hdrmod->sm_hm_type = SM_HM_TYPE_INSERT;
	sm_hdrmod->sm_hm_pos = 1;
	sm_hdrmod->sm_hm_hdr = sm_cstr_scpyn((const uchar *) HDR2_I1,
					strlen(HDR2_I1));
	SM_TEST(sm_hdrmod->sm_hm_hdr != NULL);
	ret = sm_hdrmod_insert(sm_hdrmodhd, sm_hdrmod);
	SM_TEST(sm_is_success(ret));

	sm_hdrmod = HDRMODL_FIRST(sm_hdrmodhd);
	chkhdrmod(sm_hdrmod, SM_HM_TYPE_PREPEND , 0, HDR1);

	sm_hdrmod = HDRMODL_NEXT(sm_hdrmod);
	chkhdrmod(sm_hdrmod, SM_HM_TYPE_PREPEND , 0, HDR2);

	sm_hdrmod = HDRMODL_NEXT(sm_hdrmod);
	chkhdrmod(sm_hdrmod, SM_HM_TYPE_INSERT, 1, HDR2_I1);

	sm_hdrmod = HDRMODL_NEXT(sm_hdrmod);
	chkhdrmod(sm_hdrmod, SM_HM_TYPE_INSERT, 2, HDR2_I2);

	sm_hdrmod = HDRMODL_NEXT(sm_hdrmod);
	chkhdrmod(sm_hdrmod, SM_HM_TYPE_REMOVE , 3, NULL);

	sm_hdrmod = HDRMODL_NEXT(sm_hdrmod);
	chkhdrmod(sm_hdrmod, SM_HM_TYPE_APPEND, 0, HDR3);

	sm_hdrmod = HDRMODL_NEXT(sm_hdrmod);
	chkhdrmod(sm_hdrmod, SM_HM_TYPE_APPEND, 0, HDR4);

	sm_hdrmod = HDRMODL_NEXT(sm_hdrmod);
	SM_TEST(sm_hdrmod == HDRMODL_END(sm_hdrmodhd));



	/* end */
	ret = sm_hdrmodl_free(&sm_hdrmodhd);
	SM_TEST(sm_is_success(ret));
	SM_TEST(NULL == sm_hdrmodhd);
}

static void
usage(const char *prg)
{
	sm_io_fprintf(smioerr,
		"%s: usage: %s [options] [mail]\n"
		"options:\n"
		, prg, prg
		);
	exit(EX_USAGE);
}

int
main(int argc, char **argv)
{
	int c;
	char *prg;

	prg = argv[0];
	while ((c = getopt(argc, argv, "s:V")) != -1)
	{
		switch (c)
		{
		  case 'V':
			++Verbose;
			break;
		  default:
			usage(prg);
			break;
		}
	}
	sm_test_begin(argc, argv, "test hdrmodh 0");
	argc -= optind;
	argv += optind;

	testhdrmod0();
	testhdrmodins();

	return sm_test_end();
}


syntax highlighted by Code2HTML, v. 0.9.1