// Copyright 2018 The Wuffs Authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//    https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

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

#ifndef WUFFS_INCLUDE_GUARD
#error "Wuffs' .h files need to be included before this file"
#endif

volatile int* intentional_segfault_ptr = NULL;

void  //
intentional_segfault() {
  *intentional_segfault_ptr = 0;
}

const char*  //
fuzz(wuffs_base__io_buffer* src, uint32_t hash);

static const char*  //
llvmFuzzerTestOneInput(const uint8_t* data, size_t size) {
  // Hash input as per https://en.wikipedia.org/wiki/Jenkins_hash_function
  size_t i = 0;
  uint32_t hash = 0;
  while (i != size) {
    hash += data[i++];
    hash += hash << 10;
    hash ^= hash >> 6;
  }
  hash += hash << 3;
  hash ^= hash >> 11;
  hash += hash << 15;

  wuffs_base__io_buffer src = ((wuffs_base__io_buffer){
      .data = ((wuffs_base__slice_u8){
          .ptr = (uint8_t*)(data),
          .len = size,
      }),
      .meta = ((wuffs_base__io_buffer_meta){
          .wi = size,
          .ri = 0,
          .pos = 0,
          .closed = true,
      }),
  });

  const char* msg = fuzz(&src, hash);
  if (msg) {
    if (strnlen(msg, 2047) >= 2047) {
      msg = "fuzzlib: internal error: error message is too long";
    }
    if (strstr(msg, "internal error:")) {
      fprintf(stderr, "internal errors shouldn't occur: \"%s\"\n", msg);
      intentional_segfault();
    }
  }
  return msg;
}

#ifdef __cplusplus
extern "C" {
#endif

int  //
LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
  llvmFuzzerTestOneInput(data, size);
  return 0;
}

#ifdef __cplusplus
}  // extern "C"
#endif

static wuffs_base__io_buffer  //
make_limited_reader(wuffs_base__io_buffer b, uint64_t limit) {
  uint64_t n = b.meta.wi - b.meta.ri;
  bool closed = b.meta.closed;
  if (n > limit) {
    n = limit;
    closed = false;
  }

  wuffs_base__io_buffer ret;
  ret.data.ptr = b.data.ptr + b.meta.ri;
  ret.data.len = n;
  ret.meta.wi = n;
  ret.meta.ri = 0;
  ret.meta.pos = wuffs_base__u64__sat_add(b.meta.pos, b.meta.ri);
  ret.meta.closed = closed;
  return ret;
}

#ifdef WUFFS_CONFIG__FUZZLIB_MAIN

#include <dirent.h>
#include <errno.h>
#include <fcntl.h>
#include <stdbool.h>
#include <sys/mman.h>
#include <sys/stat.h>
#include <unistd.h>

struct {
  int remaining_argc;
  char** remaining_argv;

  bool color;
} flags = {0};

const char*  //
parse_flags(int argc, char** argv) {
  int c = (argc > 0) ? 1 : 0;  // Skip argv[0], the program name.
  for (; c < argc; c++) {
    char* arg = argv[c];
    if (*arg++ != '-') {
      break;
    }

    // A double-dash "--foo" is equivalent to a single-dash "-foo". As special
    // cases, a bare "-" is not a flag (some programs may interpret it as
    // stdin) and a bare "--" means to stop parsing flags.
    if (*arg == '\x00') {
      break;
    } else if (*arg == '-') {
      arg++;
      if (*arg == '\x00') {
        c++;
        break;
      }
    }

    if (!strcmp(arg, "c") || !strcmp(arg, "color")) {
      flags.color = true;
      continue;
    }

    return "main: unrecognized flag argument";
  }

  flags.remaining_argc = argc - c;
  flags.remaining_argv = argv + c;
  return NULL;
}

static int num_files_processed;

static struct {
  char buf[PATH_MAX];
  size_t len;
} relative_cwd;

void  //
errorf(const char* msg) {
  if (flags.color) {
    printf("\e[31m%s\e[0m\n", msg);
  } else {
    printf("%s\n", msg);
  }
}

static int  //
visit(char* filename);

static int  //
visit_dir(int fd) {
  int cwd_fd = open(".", O_RDONLY, 0);
  if (fchdir(fd)) {
    errorf("failed");
    fprintf(stderr, "FAIL: fchdir: %s\n", strerror(errno));
    return 1;
  }

  DIR* d = fdopendir(fd);
  if (!d) {
    errorf("failed");
    fprintf(stderr, "FAIL: fdopendir: %s\n", strerror(errno));
    return 1;
  }

  printf("dir\n");
  while (true) {
    struct dirent* e = readdir(d);
    if (!e) {
      break;
    }
    if ((e->d_name[0] == '\x00') || (e->d_name[0] == '.')) {
      continue;
    }
    int v = visit(e->d_name);
    if (v) {
      return v;
    }
  }

  if (closedir(d)) {
    fprintf(stderr, "FAIL: closedir: %s\n", strerror(errno));
    return 1;
  }
  if (fchdir(cwd_fd)) {
    fprintf(stderr, "FAIL: fchdir: %s\n", strerror(errno));
    return 1;
  }
  if (close(cwd_fd)) {
    fprintf(stderr, "FAIL: close: %s\n", strerror(errno));
    return 1;
  }
  return 0;
}

static int  //
visit_reg(int fd, off_t size) {
  if ((size < 0) || (0x7FFFFFFF < size)) {
    errorf("failed");
    fprintf(stderr, "FAIL: file size out of bounds");
    return 1;
  }

  void* data = NULL;
  if (size > 0) {
    data = mmap(NULL, size, PROT_READ, MAP_SHARED, fd, 0);
    if (data == MAP_FAILED) {
      errorf("failed");
      fprintf(stderr, "FAIL: mmap: %s\n", strerror(errno));
      return 1;
    }
  }

  const char* msg = llvmFuzzerTestOneInput((const uint8_t*)(data), size);
  if (msg) {
    errorf(msg);
  } else if (flags.color) {
    printf("\e[32mok\e[0m\n");
  } else {
    printf("ok\n");
  }

  if ((size > 0) && munmap(data, size)) {
    fprintf(stderr, "FAIL: mmap: %s\n", strerror(errno));
    return 1;
  }
  if (close(fd)) {
    fprintf(stderr, "FAIL: close: %s\n", strerror(errno));
    return 1;
  }
  return 0;
}

static int  //
visit(char* filename) {
  num_files_processed++;
  if (!filename || (filename[0] == '\x00')) {
    fprintf(stderr, "FAIL: invalid filename\n");
    return 1;
  }
  int n = printf("- %s%s", relative_cwd.buf, filename);
  printf("%*s", (60 > n) ? (60 - n) : 1, "");
  fflush(stdout);

  struct stat z;
  int fd = open(filename, O_RDONLY, 0);
  if (fd == -1) {
    errorf("failed");
    fprintf(stderr, "FAIL: open: %s\n", strerror(errno));
    return 1;
  }
  if (fstat(fd, &z)) {
    errorf("failed");
    fprintf(stderr, "FAIL: fstat: %s\n", strerror(errno));
    return 1;
  }

  if (S_ISREG(z.st_mode)) {
    return visit_reg(fd, z.st_size);
  } else if (!S_ISDIR(z.st_mode)) {
    printf("skipped\n");
    return 0;
  }

  size_t old_len = relative_cwd.len;
  size_t filename_len = strlen(filename);
  size_t new_len = old_len + strlen(filename);
  bool slash = filename[filename_len - 1] != '/';
  if (slash) {
    new_len++;
  }
  if ((filename_len >= PATH_MAX) || (new_len >= PATH_MAX)) {
    errorf("failed");
    fprintf(stderr, "FAIL: path is too long\n");
    return 1;
  }
  memcpy(relative_cwd.buf + old_len, filename, filename_len);

  if (slash) {
    relative_cwd.buf[new_len - 1] = '/';
  }
  relative_cwd.buf[new_len] = '\x00';
  relative_cwd.len = new_len;

  int v = visit_dir(fd);

  relative_cwd.buf[old_len] = '\x00';
  relative_cwd.len = old_len;
  return v;
}

int  //
main(int argc, char** argv) {
  num_files_processed = 0;
  relative_cwd.len = 0;

  const char* z = parse_flags(argc, argv);
  if (z) {
    fprintf(stderr, "FAIL: %s\n", z);
    return 1;
  }
  int i;
  for (i = 0; i < flags.remaining_argc; i++) {
    int v = visit(flags.remaining_argv[i]);
    if (v) {
      return v;
    }
  }

  printf("PASS: %d files processed\n", num_files_processed);
  return 0;
}

#endif  // WUFFS_CONFIG__FUZZLIB_MAIN
