// Copyright (c) 2019, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

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

#include "bin/dartutils.h"
#include "platform/text_buffer.h"
#include "platform/unicode.h"
#include "platform/utils.h"
#include "vm/json_writer.h"

// Defines target function.
static int target = 0;

// Target function that stresses some unicode methods.
// Found: http://dartbug.com/36235
static int TestUnicode(const uint8_t* Data, size_t Size) {
  dart::Utf8::Type type = dart::Utf8::kLatin1;
  dart::Utf8::CodeUnitCount(Data, Size, &type);
  dart::Utf8::IsValid(Data, Size);
  int32_t dst = 0;
  dart::Utf8::Decode(Data, Size, &dst);
  uint16_t dst16[1024];
  dart::Utf8::DecodeToUTF16(Data, Size, dst16, 1024);
  int32_t dst32[1024];
  dart::Utf8::DecodeToUTF32(Data, Size, dst32, 1024);
  dart::Utf8::ReportInvalidByte(Data, Size, 1024);
  return 0;
}

// Target function that stresses various utilities.
// Found: http://dartbug.com/36818
static int TestUtilities(const uint8_t* Data, size_t Size) {
  dart::Utils::StringHash(reinterpret_cast<const char*>(Data), Size);
  dart::bin::DartUtils::SniffForMagicNumber(Data, Size);
  // Text buffer.
  dart::TextBuffer buffer(1);
  for (size_t i = 0; i < Size; i++) {
    buffer.AddChar(Data[i]);
  }
  if (static_cast<size_t>(buffer.length()) != Size) return 1;
  buffer.AddRaw(Data, Size);
  if (static_cast<size_t>(buffer.length()) != 2 * Size) return 1;
  free(buffer.Steal());
  buffer.AddRaw(Data, Size);
  if (static_cast<size_t>(buffer.length()) != Size) return 1;
  // Json writer.
  dart::JSONWriter writer(1);
  writer.OpenObject("object");
  writer.AppendBytes(Data, Size);
  writer.CloseObject();
  for (size_t i = 0; i < Size; i++) {
    writer.PrintValue(static_cast<intptr_t>(Data[i]));
  }
  writer.PrintValueBase64(Data, Size);
  return 0;
}

// Dart VM specific initialization.
static int InitDartVM() {
  // TODO(ajcbik): one-time setup of Dart VM.
  return 0;
}

// Libfuzzer one time initialization.
extern "C" int LLVMFuzzerInitialize(int* argc_in, char*** argv_in) {
  // Parse --t=<target> from command line.
  int argc = *argc_in;
  char** argv = *argv_in;
  while (--argc > 0) {
    char* ptr = *++argv;
    if (*ptr++ == '-' && *ptr++ == '-' && *ptr++ == 't' && *ptr++ == '=') {
      target = atoi(ptr);
    }
  }
  // Initialize Dart VM.
  return InitDartVM();
}

// Libfuzzer target functions:
//  0 : unicode
//  1 : utilities
extern "C" int LLVMFuzzerTestOneInput(const uint8_t* Data, size_t Size) {
  switch (target) {
    case 0:
      return TestUnicode(Data, Size);
    case 1:
      return TestUtilities(Data, Size);
    default:
      fprintf(stderr, "dart_libfuzzer: invalid target --t=%d\n", target);
      return 1;
  }
}
