// Copyright 2016 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include <errno.h>
#include <fcntl.h>
#include <fuchsia/hardware/i2c/c/fidl.h>
#include <lib/fdio/directory.h>
#include <lib/fdio/fd.h>
#include <lib/fdio/fdio.h>
#include <lib/fdio/unsafe.h>
#include <stddef.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <zircon/syscalls.h>
#include <zircon/types.h>

const char* prog_name;

void print_usage(void) {
  printf("Usage:\n");
  printf("\n");
  printf("%s DEVICE COMMAND [command arguments]\n", prog_name);
  printf("DEVICE is either the i2c bus or i2c slave COMMAND applies to.\n");
  printf("COMMAND is one of the following commands, optionally followed \n");
  printf("arguments which are specific to each command.\n");
  printf("\n");
  printf("read LENGTH: Read data from the target slave device.\n");
  printf("LENGTH is the number of bytes to read in decimal.\n");
  printf("\n");
  printf("write [data]: Write data to the target slave device.\n");
  printf("data is a sequence of hex values which each represent one byte\n");
  printf("of data to write to the target device.\n");
  printf("\n");
  printf("transfer [segments]: Perform a transfer to/from the i2c slave.\n");
  printf("segments is a series of segment descriptions which are a\n");
  printf("direction, a length, and then (for writes) a series of bytes\n");
  printf("in hexadecimal.\n");
  printf("\n");
  printf("The direction is specified as either \"w\" for writes, or\n");
  printf("\"r\" for reads.\n");
  printf("\n");
  printf("For example, to perform a write of one byte and then a read\n");
  printf("of one byte without giving up the bus:\n");
  printf("%s [dev] transfer w 1 00 r 1\n", prog_name);
}

int cmd_read(int fd, int argc, const char** argv) {
  if (argc < 1) {
    print_usage();
    return 1;
  }

  errno = 0;
  long int length = strtol(argv[0], NULL, 10);
  if (errno) {
    print_usage();
    return errno;
  }

  uint8_t* buf = malloc(length);
  if (!buf) {
    printf("Failed to allocate buffer.\n");
    return 1;
  }

  ssize_t ret = read(fd, buf, length);
  if (ret < 0) {
    printf("Error reading from slave. (%zd)\n", ret);
    goto cmd_read_finish;
  }

  for (int i = 0; i < length; i++) {
    printf(" %02x", buf[i]);
    if (i % 32 == 31)
      printf("\n");
  }
  printf("\n");

cmd_read_finish:
  free(buf);
  return (int)ret;
}

int cmd_write(int fd, int argc, const char** argv) {
  if (argc < 1) {
    print_usage();
    return 1;
  }

  uint8_t* buf = malloc(argc);
  if (!buf) {
    printf("Failed to allocate buffer.\n");
    return 1;
  }

  size_t ret = 0;

  errno = 0;
  for (int i = 0; i < argc; i++) {
    buf[i] = (uint8_t)strtol(argv[i], NULL, 16);
    if (errno) {
      ret = errno;
      print_usage();
      goto cmd_write_finish;
    }
  }

  ret = write(fd, buf, argc);
  if (ret < 0)
    printf("Error writing to slave. (%zd)\n", ret);

cmd_write_finish:
  free(buf);
  return (int)ret;
}

int cmd_transfer(int fd, int argc, const char** argv) {
  const size_t base_size = sizeof(fuchsia_hardware_i2c_Segment);
  int ret = ZX_OK;

  // Figure out how big our buffers need to be.
  // Start the counters with enough space for the fuchsia_hardware_i2c_SegmentType_END
  // segment.
  size_t in_len = base_size;
  size_t out_len = 0;
  int segments = 1;
  int count = argc;
  const char** arg = argv;
  errno = 0;
  while (count) {
    if (count < 2) {
      print_usage();
      goto cmd_transfer_finish_2;
    }

    in_len += base_size;

    int read;
    if (!strcmp(arg[0], "r")) {
      read = 1;
    } else if (!strcmp(arg[0], "w")) {
      read = 0;
    } else {
      print_usage();
      goto cmd_transfer_finish_2;
    }
    segments++;

    long int length = strtol(arg[1], NULL, 10);
    if (errno) {
      print_usage();
      return errno;
    }
    arg += 2;
    count -= 2;
    if (read) {
      out_len += length;
    } else {
      in_len += length;
      if (length > count) {
        print_usage();
        goto cmd_transfer_finish_2;
      }
      arg += length;
      count -= length;
    }
  }

  // Allocate the input and output buffers.
  void* in_buf = malloc(in_len);
  void* out_buf = malloc(out_len);
  if (!in_buf || !out_buf) {
    ret = 1;
    goto cmd_transfer_finish_1;
  }
  uint8_t* data_addr = (uint8_t*)in_buf + segments * base_size;
  uint8_t* data_buf = data_addr;

  // Fill the "input" buffer which is sent via FIDL.
  uintptr_t in_addr = (uintptr_t)in_buf;
  int i = 0;
  fuchsia_hardware_i2c_Segment* segment = (fuchsia_hardware_i2c_Segment*)in_addr;
  while (i < argc) {
    if (!strcmp(argv[i++], "r")) {
      segment->type = fuchsia_hardware_i2c_SegmentType_READ;
      unsigned long len = strtoul(argv[i++], NULL, 10);
      if (errno) {
        print_usage();
        return errno;
      }
      if (len >= UINT32_MAX) {
        print_usage();
        return -1;
      }
      segment->len = (uint32_t)len;
    } else {
      segment->type = fuchsia_hardware_i2c_SegmentType_WRITE;
      unsigned long len = strtoul(argv[i++], NULL, 10);
      if (errno) {
        print_usage();
        return errno;
      }
      if (len >= UINT32_MAX) {
        print_usage();
        return -1;
      }
      segment->len = (uint32_t)len;

      for (uint32_t seg = 0; seg < segment->len; seg++) {
        unsigned long val = strtoul(argv[i++], NULL, 16);
        if (errno) {
          print_usage();
          return errno;
        }
        if (val >= UINT8_MAX) {
          print_usage();
          return -1;
        }
        *data_buf++ = (uint8_t)val;
      }
    }
    segment++;
  }
  segment->type = fuchsia_hardware_i2c_SegmentType_END;
  segment->len = 0;
  segment++;
  // We should be at the start of the data section now.
  if ((uint8_t*)segment != data_addr) {
    ret = 1;
    goto cmd_transfer_finish_1;
  }

  fdio_t* io = fdio_unsafe_fd_to_io(fd);  // Get a fdio channel from the fd.
  if (io == NULL)
    return ZX_ERR_INVALID_ARGS;
  zx_status_t status;
  size_t out_actual;
  zx_status_t res = fuchsia_hardware_i2c_DeviceSubordinateTransfer(
      fdio_unsafe_borrow_channel(io), in_buf, in_len, &status, out_buf, out_len, &out_actual);
  fdio_unsafe_release(io);  // Release the channel manually.
  if (out_actual < out_len) {
    status = ZX_ERR_BUFFER_TOO_SMALL;
  }
  if (res == ZX_OK) {
    res = status;
  }
  if (res != ZX_OK) {
    printf("Error in transfer to/from slave. (%d)\n", res);
    goto cmd_transfer_finish_1;
  }

  for (size_t i = 0; i < out_len; i++) {
    printf(" %02x", ((uint8_t*)out_buf)[i]);
    if (i % 32 == 31)
      printf("\n");
  }
  printf("\n");

  ret = 0;

cmd_transfer_finish_1:
  free(in_buf);
  free(out_buf);
cmd_transfer_finish_2:
  return ret;
}

int main(int argc, const char** argv) {
  if (argc < 1)
    return 1;

  prog_name = argv[0];

  if (argc < 3) {
    print_usage();
    return 1;
  }

  const char* dev = argv[1];
  const char* cmd = argv[2];

  argc -= 3;
  argv += 3;

  int fd = open(dev, O_RDWR);
  if (fd < 0) {
    printf("Error opening I2C device.\n");
    return 1;
  }

  if (!strcmp("read", cmd)) {
    return cmd_read(fd, argc, argv);
  } else if (!strcmp("write", cmd)) {
    return cmd_write(fd, argc, argv);
  } else if (!strcmp("transfer", cmd)) {
    return cmd_transfer(fd, argc, argv);
  } else {
    printf("Unrecognized command %s.\n", cmd);
    print_usage();
    return 1;
  }

  printf("We should never get here!.\n");
  return 1;
}
