#include <alias/glob.h>

bool alias_glob_match(alias_str pattern, alias_str string) {
  for(;;) {
    if(*pattern == 0 && *string == 0) {
      return true;
    }

    if(*pattern == 0) {
      return false;
		}
    
    if(*pattern == '*') {
      pattern++;
      if(*pattern == 0) {
        return true;
      }
      while(*string) {
        if(alias_glob_match(pattern, string)) {
          return true;
        }
        string++;
      }
      return false;
    }

    if(*string == 0) {
      return false;
    }

    if(*pattern == '?') {
      pattern++;
      string++;
      continue;
    }

    if(*pattern == '[') {
      pattern++;
      uint32_t ascii[8] = {0};
      bool negate = *pattern == '!';
      pattern += negate;
      if(pattern[1] == '-' && pattern[3] == ']') {
        for(uint32_t i = pattern[0]; i < pattern[2]; i++) {
          if(i <= 255) {
            ascii[i >> 5] |= 1 << (i & 31);
          }
        }
        pattern += 4;
      } else {
        while(*pattern && *pattern != ']') {
          ascii[*pattern >> 5] |= 1 << (*pattern & 31);
          pattern++;
        }
        pattern++;
      }
      if(negate) {
        for(uint32_t i = 0; i < 8; i++) {
          ascii[i] ^= 0xFFFFFFFFu;
        }
      }
      if(ascii[*string >> 5] & (1 << (*string & 31))) {
        string++;
        continue;
      }
      return false;
    }

    if(*pattern != *string) {
      return false;
    }
    pattern++;
    string++;
  }
}