#include <stdint.h>
#include <stddef.h>
#include "hal.h"

void *hal_memset(void *p, int c, size_t n) {
  char *cp = p;
  for (size_t i = 0; i < n; i++) cp[i] = c;
  return p;
}

void *hal_memcpy(void *dst, const void *src, size_t n) {
  char *a = dst;
  const char *b = src;
  for (size_t i = 0; i < n; i++) a[i] = b[i];
  return dst;
}

size_t hal_strlen(char *s) {
  char *s2;
  for (s2 = s; *s2; ++s2);
  return (s2 - s);
}

// https://aticleworld.com/memcmp-in-c/
int hal_memcmp(const void *s1, const void *s2, int len)
{
    unsigned char *p = (unsigned char *)s1;
    unsigned char *q = (unsigned char *)s2;
    int charCompareStatus = 0;
    //If both pointer pointing same memory block
    if (s1 == s2)
    {
        return charCompareStatus;
    }
    while (len > 0)
    {
        if (*p != *q)
        {  //compare the mismatching character
            charCompareStatus = (*p >*q)?1:-1;
            break;
        }
        len--;
        p++;
        q++;
    }
    return charCompareStatus;
}

int hal_strcmp(const char *a, const char *b) {
  while (*a && (*a == *b)) {
    a++, b++;
  }
  return (unsigned char)*a - (unsigned char)*b;
}

size_t hal_strcspn(const char *s, const char *reject) {
    size_t count = 0;
    for (; *s != '\0'; ++s) {
        const char *r = reject;
        while (*r != '\0') {
            if (*s == *r) {
                return count;
            }
            r++;
        }
        count++;
    }
    return count;
}

size_t hal_strspn(const char *s, const char *accept) {
    size_t count = 0;
    for (; *s != '\0'; ++s) {
        const char *a = accept;
        int matched = 0;
        while (*a != '\0') {
            if (*s == *a) {
                matched = 1;
                break;
            }
            a++;
        }
        if (!matched) {
            return count;
        }
        count++;
    }
    return count;
}

char *hal_strcpy(char *dest, const char *src) {
    char *d = dest;
    while ((*d++ = *src++) != '\0') {
        ;
    }
    return dest;
}

char *hal_strchr(const char *s, int c) {
    char ch = (char)c;
    while (*s != '\0') {
        if (*s == ch) {
            return (char *)s;
        }
        s++;
    }
    if (ch == '\0') {
        return (char *)s;
    }
    return NULL;
}
