// Copyright 2026 The IREE Authors
//
// Licensed under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception

// <stdio.h> for wasm32.
//
// IREE uses eyalroz/printf for all formatted output. The snprintf/vsnprintf
// functions here are thin wrappers that defer to the eyalroz library via the
// IREE printf API (iree_snprintf, etc.). The printf/fprintf functions that
// write to streams use the iree_wasm_write syscall import.
//
// FILE is a minimal struct — just enough to carry a file descriptor. No
// buffering, no seeking, no real filesystem. stdout and stderr write to the
// JS console via the write import. stdin always returns EOF.

#include <stdarg.h>
#include <stdint.h>
#include <stdio.h>
#include <string.h>

#include "syscall_imports.h"

//===----------------------------------------------------------------------===//
// FILE implementation
//===----------------------------------------------------------------------===//

struct _iree_wasm_file {
  int fd;
  int error;
  int eof;
};

static struct _iree_wasm_file stdin_file = {0, 0, 1};  // Always EOF.
static struct _iree_wasm_file stdout_file = {1, 0, 0};
static struct _iree_wasm_file stderr_file = {2, 0, 0};

FILE* stdin = &stdin_file;
FILE* stdout = &stdout_file;
FILE* stderr = &stderr_file;

//===----------------------------------------------------------------------===//
// Formatted output — delegated to IREE's printf API.
//
// IREE's printf.c provides iree_vsnprintf. The libc snprintf/vsnprintf below
// are provided for code that calls the standard names directly.
//===----------------------------------------------------------------------===//

extern int iree_vsnprintf(char* buffer, size_t count, const char* format,
                          va_list args);

int snprintf(char* buffer, size_t count, const char* format, ...) {
  va_list args;
  va_start(args, format);
  int result = iree_vsnprintf(buffer, count, format, args);
  va_end(args);
  return result;
}

int vsnprintf(char* buffer, size_t count, const char* format, va_list args) {
  return iree_vsnprintf(buffer, count, format, args);
}

int sprintf(char* buffer, const char* format, ...) {
  va_list args;
  va_start(args, format);
  int result = iree_vsnprintf(buffer, (size_t)-1, format, args);
  va_end(args);
  return result;
}

int vsprintf(char* buffer, const char* format, va_list args) {
  return iree_vsnprintf(buffer, (size_t)-1, format, args);
}

//===----------------------------------------------------------------------===//
// Stream output — writes to JS console via wasm import.
//===----------------------------------------------------------------------===//

// Formatting buffer for printf/fprintf. 4KB is generous for single format
// calls. If a single printf produces more than this, the output is truncated.
// IREE's own formatting always uses snprintf with explicit buffers, so this
// limit only affects third-party code calling printf directly.
#define PRINTF_BUFFER_SIZE 4096

int printf(const char* format, ...) {
  char buffer[PRINTF_BUFFER_SIZE];
  va_list args;
  va_start(args, format);
  int length = iree_vsnprintf(buffer, sizeof(buffer), format, args);
  va_end(args);
  if (length > 0) {
    int write_length =
        length < (int)sizeof(buffer) ? length : (int)sizeof(buffer) - 1;
    iree_wasm_write(1, buffer, write_length);
  }
  return length;
}

int vprintf(const char* format, va_list args) {
  char buffer[PRINTF_BUFFER_SIZE];
  int length = iree_vsnprintf(buffer, sizeof(buffer), format, args);
  if (length > 0) {
    int write_length =
        length < (int)sizeof(buffer) ? length : (int)sizeof(buffer) - 1;
    iree_wasm_write(1, buffer, write_length);
  }
  return length;
}

int fprintf(FILE* stream, const char* format, ...) {
  char buffer[PRINTF_BUFFER_SIZE];
  va_list args;
  va_start(args, format);
  int length = iree_vsnprintf(buffer, sizeof(buffer), format, args);
  va_end(args);
  if (length > 0) {
    int write_length =
        length < (int)sizeof(buffer) ? length : (int)sizeof(buffer) - 1;
    iree_wasm_write(stream->fd, buffer, write_length);
  }
  return length;
}

int vfprintf(FILE* stream, const char* format, va_list args) {
  char buffer[PRINTF_BUFFER_SIZE];
  int length = iree_vsnprintf(buffer, sizeof(buffer), format, args);
  if (length > 0) {
    int write_length =
        length < (int)sizeof(buffer) ? length : (int)sizeof(buffer) - 1;
    iree_wasm_write(stream->fd, buffer, write_length);
  }
  return length;
}

//===----------------------------------------------------------------------===//
// Character and string I/O
//===----------------------------------------------------------------------===//

int fputc(int character, FILE* stream) {
  char c = (char)character;
  int32_t result = iree_wasm_write(stream->fd, &c, 1);
  return result == 1 ? (unsigned char)c : EOF;
}

int fputs(const char* string, FILE* stream) {
  size_t length = strlen(string);
  int32_t result = iree_wasm_write(stream->fd, string, (int32_t)length);
  return result >= 0 ? result : EOF;
}

int fgetc(FILE* stream) {
  (void)stream;
  return EOF;  // No input on freestanding wasm.
}

int getchar(void) { return EOF; }

int ungetc(int character, FILE* stream) {
  (void)character;
  (void)stream;
  return EOF;
}

//===----------------------------------------------------------------------===//
// Block I/O
//===----------------------------------------------------------------------===//

size_t fread(void* buffer, size_t size, size_t count, FILE* stream) {
  (void)buffer;
  (void)size;
  (void)count;
  (void)stream;
  return 0;  // No input on freestanding wasm.
}

size_t fwrite(const void* buffer, size_t size, size_t count, FILE* stream) {
  if (size == 0 || count == 0) return 0;
  size_t total = size * count;

  // Detect size*count overflow and int32_t truncation. The wasm import takes
  // int32_t, so we cannot write more than INT32_MAX bytes in a single call.
  if (total / size != count || total > (size_t)INT32_MAX) {
    stream->error = 1;
    return 0;
  }

  int32_t result = iree_wasm_write(stream->fd, buffer, (int32_t)total);
  if (result < 0) {
    stream->error = 1;
    return 0;
  }
  return (size_t)result / size;
}

int fflush(FILE* stream) {
  (void)stream;
  return 0;  // No buffering.
}

//===----------------------------------------------------------------------===//
// File operations (stubs)
//===----------------------------------------------------------------------===//

FILE* fopen(const char* pathname, const char* mode) {
  (void)pathname;
  (void)mode;
  return NULL;
}

FILE* fdopen(int fd, const char* mode) {
  (void)fd;
  (void)mode;
  return NULL;
}

FILE* freopen(const char* pathname, const char* mode, FILE* stream) {
  (void)pathname;
  (void)mode;
  (void)stream;
  return NULL;
}

int fclose(FILE* stream) {
  (void)stream;
  return 0;
}

int fseek(FILE* stream, long offset, int whence) {
  (void)stream;
  (void)offset;
  (void)whence;
  return -1;
}

long ftell(FILE* stream) {
  (void)stream;
  return -1;
}

void rewind(FILE* stream) { (void)stream; }
int feof(FILE* stream) { return stream->eof; }
int ferror(FILE* stream) { return stream->error; }
void clearerr(FILE* stream) {
  stream->error = 0;
  stream->eof = 0;
}

int fileno(FILE* stream) { return stream->fd; }

int remove(const char* pathname) {
  (void)pathname;
  return -1;
}

int rename(const char* oldpath, const char* newpath) {
  (void)oldpath;
  (void)newpath;
  return -1;
}
