/* $Id: packstr.c,v 1.8 2002/06/23 20:28:31 richdawe Exp $ */

/*
 * packstr.c - Test parsing of package strings for user-interfacing code.
 * Copyright (C) 2000-2002 by Richard Dawe
 */

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include <libpakke/package.h>
#include <libpakke/user.h>

/* Sanity checks */
#if PACKAGE_VERSION_N_HAS != 14
#error "Need to update test to cope with PACKAGE_VERSION's has_*"
#endif

#if PACKAGE_VERSION_N_DATA != 21
#error "Need to update test to cope with PACKAGE_VERSION's data fields"
#endif

/* Test case */
typedef struct {
  const char      *str;

  /* Expected results */
  const char      *name;
  PACKAGE_VERSION  ver;
} testcase_t;

testcase_t testcases[] = {
  /* Simple cases using grep */
  {
    "grep 2.2 (binaries)", "grep",
    {
      1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, /* has_* */
      2, 2, /* major, minor */
      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* int version components */
      NULL, NULL, NULL, NULL, /* platform components */
      TYPE_BINARIES
    },
  },

  {
    "grep 2.2 (sources)", "grep",
    {
      1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, /* has_* */
      2, 2, /* major, minor */
      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* int version components */
      NULL, NULL, NULL, NULL, /* platform components */
      TYPE_SOURCES
    },
  },

  {
    "grep 2.2 (documentation)", "grep",
    {
      1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, /* has_* */
      2, 2, /* major, minor */
      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* int version components */
      NULL, NULL, NULL, NULL, /* platform components */
      TYPE_DOCUMENTATION
    },
  },

  /* Kitchen sink cases */
  {
    "kitchen-sink 1.2.3.4 (group)", "kitchen-sink",
    {
      1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, /* has_* */
      1, 2, 0, 3, 0, 4, 0, /* major, minor, subminor, subsubminor */
      0, 0, 0, 0, 0, 0, 0, 0, 0, /* int version components */
      NULL, NULL, NULL, NULL, /* platform components */
      TYPE_GROUP
    },
  },

  {
    "kitchen-sink 1.2.3.4 " /* continued */
    "alpha 10 revision 11 patchlevel 12 snapshot 20001210 (group)",
    "kitchen-sink",
    {
      1, 1, 1, 1, 1, 1, 0, 0, 1, 1, 1, 0, 0, 1, /* has_* */
      1, 2, 0, 3, 0, 4, 0, /* major, minor, subminor, subsubminor */
      10, 0, 0, 11, 12, 2000, 12, 10, 0, /* int version components */
      NULL, NULL, NULL, NULL, /* platform components */
      TYPE_GROUP
    },
  },

  {
    "kitchen-sink 1.2.3.4 " /* continued */
    "beta 10 revision 11 patchlevel 12 snapshot 20001210 (virtual)",
    "kitchen-sink",
    {
      1, 1, 1, 1, 1, 0, 1, 0, 1, 1, 1, 0, 0, 1, /* has_* */
      1, 2, 0, 3, 0, 4, 0, /* major, minor, subminor, subsubminor */
      0, 10, 0, 11, 12, 2000, 12, 10, 0, /* int version components */
      NULL, NULL, NULL, NULL, /* platform components */
      TYPE_VIRTUAL
    },
  },

  {
    "kitchen-sink 1.2.3.4 " /* continued */
    "pre 10 revision 11 patchlevel 12 snapshot 20001210 (sources)",
    "kitchen-sink",
    {
      1, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1, 0, 0, 1, /* has_* */
      1, 2, 0, 3, 0, 4, 0, /* major, minor, subminor, subsubminor */
      0, 0, 10, 11, 12, 2000, 12, 10, 0, /* int version components */
      NULL, NULL, NULL, NULL, /* platform components */
      TYPE_SOURCES
    },
  },

  {
    "kitchen-sink 1.2.3.4 " /* continued */
    "revision 11 patchlevel 12 snapshot 20001210 release 5 (sources)",
    "kitchen-sink",
    {
      1, 1, 1, 1, 1, 0, 0, 0, 1, 1, 1, 1, 0, 1, /* has_* */
      1, 2, 0, 3, 0, 4, 0, /* major, minor, subminor, subsubminor */
      0, 0, 0, 11, 12, 2000, 12, 10, 5, /* int version components */
      NULL, NULL, NULL, NULL, /* platform components */
      TYPE_SOURCES
    },
  },

  /* Wildcards */
  {
    "grep 2.? (binaries)", "grep",
    {
      1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, /* has_* */
      2, -1, /* major, minor */
      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* int version components */
      NULL, NULL, NULL, NULL, /* platform components */
      TYPE_BINARIES
    },
  },

  {
    "grep 2.?.1 (binaries)", "grep",
    {
      1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, /* has_* */
      2, -1, 0, 1, 0, /* major, minor, subminor */
      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* int version components */
      NULL, NULL, NULL, NULL, /* platform components */
      TYPE_BINARIES
    },
  },

  /* TODO: Finish me */
  {
    "grep 2.* (binaries)", "grep",
    {
      1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, /* has_* */
      2, -1, /* major, minor */
      -1, -1, -1, -1, -1, -1, -1, /* int version components */
      -1, -1, -1, -1, -1, -1, -1, /* int version components */
      NULL, NULL, NULL, NULL, /* platform components */
      TYPE_BINARIES
    },
  },

  /* Terminator */
  { NULL }
};

/* --------
 * - main -
 * -------- */

int
main (int argc, char *argv[])
{
  /* Vars for result of calling user_parse_package_string(). */
  char name[PACKAGE_MAXNAMELEN];
  const size_t namelen = sizeof(name);
  PACKAGE_VERSION ver;

  int quiet = 0;
  int ret   = EXIT_SUCCESS;
  int i;

  /* Parse arguments. */
  for (i = 1; i < argc; i++) {
    /* Quiet operation, for automatic testing. */
    if (   (strcmp(argv[i], "--quiet") == 0)
	|| (strcmp(argv[i], "-q") == 0))
      quiet = 1;
  }

  /* Run through the test cases. */
  for (i = 0; testcases[i].str != NULL; i++) {
    memset(name, 0, namelen);
    memset(&ver, 0, sizeof(ver));

    if (!user_parse_package_string(testcases[i].str, name, namelen, &ver)) {
      if (!quiet)
	fprintf(stderr,
		"Test case %d: Parsing failed: '%s'\n",
		i + 1, testcases[i].str);
      ret = EXIT_FAILURE;
      continue;
    }

    /* Check test results match. */
    if (strcmp(name, testcases[i].name) != 0) {
      if (!quiet)
	fprintf(stderr,
		"Test case %d: FAIL: '%s': Names do not match: "
		"'%s' vs. '%s'\n",
		i + 1, testcases[i].str, testcases[i].name, name);
      ret = EXIT_FAILURE;
      continue;
    }

    if (package_vercmp(&ver, &testcases[i].ver) != 0) {
      if (!quiet) {
	fprintf(stderr, "Test case %d: FAIL: '%s': Versions do not match: ",
		i + 1, testcases[i].str);
	fprintf(stderr, "'%s' vs. ",
		package_version_string(&testcases[i].ver));
	fprintf(stderr, "'%s'\n", package_version_string(&ver));
      }
      ret = EXIT_FAILURE;
      continue;
    }

    /* Phew, OK ;) */
    if (!quiet)
      printf("Test case %d: OK: '%s'\n", i + 1, testcases[i].str);
  }

  return(ret);
}
