/*
  t-glob.c

  Author: Sami Lehtinen <sjl@ssh.fi>

  Copyright (C) 1999 SSH Communications Security Oy, Espoo, Finland
  All rights reserved.

  Tests for sshglob.c .
  
 */

#include "sshincludes.h"
#include "sshglob.h"
#include "sshgetopt.h"

#define SSH_DEBUG_MODULE "TestSshGlob"

void test_debug(const char *msg, void *context)
{
  Boolean verbose = *(Boolean *)context;

  if (verbose)
    fprintf(stderr, "%s\n", msg);
}

void test_warning(const char *msg, void *context)
{
  Boolean verbose = *(Boolean *)context;

  if (verbose)
    fprintf(stderr, "warning: %s\n", msg);
}

int main(int argc, char **argv)
{
  Boolean verbose = FALSE;
  char *test_string, *placeholder;
  int ret;
  
  while (1)
    {
      int option;
      ssh_opterr = 0;
      ssh_optallowplus = 1;
      
      option = ssh_getopt(argc, argv, "d:v", NULL);
      
      if (option == -1)
        break;

      switch (option)
        {
        case 'd':
          ssh_debug_set_global_level(atoi(ssh_optarg));
          verbose = TRUE;
          break;
        case 'v':
          ssh_debug_set_global_level(2);
          verbose = TRUE;
          break;
        }  
    }

  ssh_debug_register_callbacks(NULL, test_warning, test_debug, &verbose);

  fprintf(stderr, "Running test for sshglob, use -v for verbose "
                  "output, and -d <level> to set debug level.\n");

  SSH_DEBUG(0, ("Running tests for ssh_glob_isescaped..."));

  test_string = "\\\\\\*";
  SSH_DEBUG(1, ("test_string \"%s\", escape '%c', should return TRUE...", \
                test_string, '\\'));
  if (!ssh_glob_isescaped(strchr(test_string, '*'), test_string))
    return 1;
  SSH_DEBUG(1, ("passed."));
  
  test_string = "\\\\*";
  SSH_DEBUG(1, ("test_string \"%s\", escape '%c', should return FALSE...", \
                test_string, '\\'));
  if (ssh_glob_isescaped(strchr(test_string, '*'), test_string))
    return 1;
  SSH_DEBUG(1, ("passed."));

  test_string = "::";
  SSH_DEBUG(1, ("test_string \"%s\", escape '%c', should return TRUE...", \
                test_string, ':'));
  if (!_ssh_glob_isescaped(&test_string[1], test_string, ':'))
    return 1;
  SSH_DEBUG(1, ("passed."));

  test_string = ":::";
  SSH_DEBUG(1, ("test_string \"%s\", escape '%c', should return FALSE...", \
                test_string, ':'));
  if (_ssh_glob_isescaped(&test_string[2], test_string, ':'))
    return 1;
  SSH_DEBUG(1, ("passed."));

  SSH_DEBUG(0, ("Running tests for ssh_glob_next_unescaped_char..."));

  test_string = "\\*\\\\*\\\\\\*\\*\\\\*";
  SSH_DEBUG(1, ("test_string \"%s\", escape '%c', should return the "   \
                "pointer to the 5th letter in the array...",            \
                test_string, '\\'));
  if ((placeholder = ssh_glob_next_unescaped_char(test_string, '*'))
      != &test_string[4])
    return 1;
  SSH_DEBUG(1, ("passed."));

  /* Skip the character. */
  placeholder++;
  
  SSH_DEBUG(1, ("placeholder \"%s\", escape '%c', should return the "     \
                "pointer to the 13th letter in the test_string array...", \
                placeholder, '\\'));
  if (ssh_glob_next_unescaped_char(placeholder, '*') != &test_string[13])
    return 1;
  SSH_DEBUG(1, ("passed."));

  SSH_DEBUG(0, ("Running tests for ssh_glob_next_unescaped_wildchar..."));

  test_string = ":::*:?::::*";
  SSH_DEBUG(1, ("test_string \"%s\", escape '%c', should return the "   \
                "pointer to the 10th letter in the array...",            \
                test_string, ':'));
  if ((placeholder = _ssh_glob_next_unescaped_wildchar(test_string, ':'))
      != &test_string[10])
    return 1;
  SSH_DEBUG(1, ("passed."));

  test_string = ":::*?::::*";
  SSH_DEBUG(1, ("test_string \"%s\", escape '%c', should return the "   \
                "pointer to the 4th letter in the array...",            \
                test_string, ':'));
  if ((placeholder = _ssh_glob_next_unescaped_wildchar(test_string, ':'))
      != &test_string[4])
    return 1;
  SSH_DEBUG(1, ("passed."));

  SSH_DEBUG(0, ("Running tests for ssh_glob_strip_escapes..."));

  test_string = "\\\\kjdf\\ksdf\\\\\\sufe";
  SSH_DEBUG(1, ("test_string \"%s\", escape '%c', should return a string " \
                "equal to \"%s\"...", test_string, '\\',                   \
                "\\kjdfksdf\\sufe"));
  placeholder = ssh_glob_strip_escapes(test_string);
  ret = strcmp(placeholder, "\\kjdfksdf\\sufe");
  if (ret)
    {
      SSH_DEBUG(1, ("returned \"%s\".", placeholder));
      ssh_xfree(placeholder);
      return 1;
    }
  ssh_xfree(placeholder);
  SSH_DEBUG(1, ("passed."));

  test_string = ":::sdafkaj:: askld:asjd:::::kjasd";
  SSH_DEBUG(1, ("test_string \"%s\", escape '%c', should return a string " \
                "equal to \"%s\"...", test_string, ':',                    \
                ":sdafkaj askld:asjd::kjasd"));
  placeholder = _ssh_glob_strip_escapes(test_string, ':');
  ret = strcmp(placeholder, ":sdafkaj: askldasjd::kjasd");
  if (ret)
    {
      SSH_DEBUG(1, ("returned \"%s\".", placeholder));
      ssh_xfree(placeholder);
      return 1;
    }
  ssh_xfree(placeholder);
  SSH_DEBUG(1, ("passed."));

  SSH_DEBUG(0, ("Running tests for ssh_glob_check_for_wildcards..."));

  test_string = "\\\\\\*";
  SSH_DEBUG(1, ("test_string \"%s\", should return FALSE...", \
                test_string));
  if (ssh_glob_check_for_wildcards(test_string))
    {
      return 1;
    }
  SSH_DEBUG(1, ("passed."));

  test_string = "\\\\*\\sfdgdsf";
  SSH_DEBUG(1, ("test_string \"%s\", should return TRUE...", \
                test_string));
  if (!ssh_glob_check_for_wildcards(test_string))
    {
      return 1;
    }
  SSH_DEBUG(1, ("passed."));

  test_string = "\\\\?";
  SSH_DEBUG(1, ("test_string \"%s\", should return TRUE...", \
                test_string));  
  if (!ssh_glob_check_for_wildcards(test_string))
    {
      return 1;
    }
  SSH_DEBUG(1, ("passed."));

  test_string = "\\\\\\?kdfhlkasjd\\\\\\\\\\*";
  SSH_DEBUG(1, ("test_string \"%s\", should return FALSE...", \
                test_string));
  if (ssh_glob_check_for_wildcards(test_string))
    {
      return 1;
    }
  SSH_DEBUG(1, ("passed."));

  SSH_DEBUG(0, ("Running tests for ssh_glob_match_pattern..."));

  test_string = ":*::skd:ksdjf";
  SSH_DEBUG(1, ("test_string \"%s\", should return TRUE...", \
                test_string));

  if (!_ssh_glob_match_pattern(test_string, "*:skdksdjf", ':'))
    {
      return 1;
    }
  SSH_DEBUG(1, ("passed."));

  test_string = "*:*:::skd:ksdjf:??";
  SSH_DEBUG(1, ("test_string \"%s\", should return TRUE...", \
                test_string));

  if (!_ssh_glob_match_pattern(test_string, "dflasjhdf*:skdksdjf?ö", ':'))
    {
      return 1;
    }
  
  SSH_DEBUG(1, ("passed."));

  test_string = "*:*::skd:ksdjf:??";
  SSH_DEBUG(1, ("test_string \"%s\", should return TRUE...", \
                test_string));

  if (!_ssh_glob_match_pattern(test_string, "dflasjhdf*:skdksdjf?ö", ':'))
    {
      return 1;
    }
  SSH_DEBUG(1, ("passed."));

  test_string = ":skd:ksdjf:??";
  SSH_DEBUG(1, ("test_string \"%s\", should return TRUE...", \
                test_string));

  if (!_ssh_glob_match_pattern(test_string, "skdksdjf?ö", ':'))
    {
      return 1;
    }
  SSH_DEBUG(1, ("passed."));

  test_string = ":??";
  SSH_DEBUG(1, ("test_string \"%s\", should return FALSE...", \
                test_string));

  if (_ssh_glob_match_pattern(test_string, "öö", ':'))
    {
      return 1;
    }
  SSH_DEBUG(1, ("passed."));

  test_string = "*ka:*";
  SSH_DEBUG(1, ("test_string \"%s\", should return FALSE...", \
                test_string));

  if (_ssh_glob_match_pattern(test_string, "ssa*", ':'))
    {
      return 1;
    }
  SSH_DEBUG(1, ("passed."));

  test_string = "::*ka:*";
  SSH_DEBUG(1, ("test_string \"%s\", should return TRUE...", \
                test_string));

  if (!_ssh_glob_match_pattern(test_string, ":paska*", ':'))
    {
      return 1;
    }
  SSH_DEBUG(1, ("passed."));

  test_string = "*:*:s"; 
  SSH_DEBUG(1, ("test_string \"%s\", should return FALSE...", \
                test_string));

  if (_ssh_glob_match_pattern(test_string, "f*:s", ':'))
    {
      return 1;
    }
  SSH_DEBUG(1, ("passed."));

  test_string = "*:*:skd:ksdjf:??"; /* Matches with 'we*skdksdjf?o'*/
  SSH_DEBUG(1, ("test_string \"%s\", should return FALSE...", \
                test_string));

  if (_ssh_glob_match_pattern(test_string, "dflasjhdf*:skdksdjf?ö", ':'))
    {
      return 1;
    }
  SSH_DEBUG(1, ("passed."));

  test_string = ":::::*:*:skd:ksdjf:??"; 
  SSH_DEBUG(1, ("test_string \"%s\", should return TRUE...", \
                test_string));

  if (!_ssh_glob_match_pattern(test_string, "::**skdksdjf?ö", ':'))
    {
      return 1;
    }
  SSH_DEBUG(1, ("passed."));

  SSH_DEBUG(0, ("passed all tests."));
  
  return 0;
}
