// Copyright 2017 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 <ctype.h>
#include <stdio.h>
#include <string.h>
#include <zircon/types.h>

#include <audio-proto-utils/format-utils.h>
#include <audio-utils/audio-device-stream.h>
#include <audio-utils/audio-input.h>
#include <audio-utils/audio-output.h>
#include <fbl/algorithm.h>
#include <fbl/auto_call.h>

#include "sine-source.h"
#include "wav-sink.h"
#include "wav-source.h"

static constexpr float DEFAULT_PLUG_MONITOR_DURATION = 10.0f;
static constexpr float MIN_PLUG_MONITOR_DURATION = 0.5f;
static constexpr float DEFAULT_TONE_DURATION = 1.5f;
static constexpr float MIN_TONE_DURATION = 0.001f;
static constexpr float DEFAULT_TONE_FREQ = 440.0f;
static constexpr float MIN_TONE_FREQ = 15.0f;
static constexpr float MAX_TONE_FREQ = 20000.0f;
static constexpr float DEFAULT_RECORD_DURATION = 30.0f;
static constexpr uint32_t DEFAULT_FRAME_RATE = 48000;
static constexpr uint32_t DEFAULT_BITS_PER_SAMPLE = 16;
static constexpr uint32_t DEFAULT_CHANNELS = 2;
static constexpr uint32_t DEFAULT_ACTIVE_CHANNELS = SineSource::kAllChannelsActive;
static constexpr audio_sample_format_t AUDIO_SAMPLE_FORMAT_UNSIGNED_8BIT =
    static_cast<audio_sample_format_t>(AUDIO_SAMPLE_FORMAT_8BIT |
                                       AUDIO_SAMPLE_FORMAT_FLAG_UNSIGNED);

enum class Command {
  INVALID,
  INFO,
  MUTE,
  UNMUTE,
  AGC,
  GAIN,
  PLUG_MONITOR,
  TONE,
  PLAY,
  RECORD,
};

void usage(const char* prog_name) {
  // clang-format off
  printf("usage:\n");
  printf("%s [options] <cmd> <cmd params>\n", prog_name);
  printf("\nOptions\n");
  printf("  When options are specified, they must occur before the command and command\n"
         "  arguments.  Valid options include...\n"
         "  -d <device id>   : Dev node id for the audio device to use.  Defaults to 0.\n"
         "  -t <device type> : The type of device to open, either input or output.  Ignored if\n"
         "                     the command given is direction specific (play, record, etc).\n"
         "                     Otherwise, defaults to output.\n"
         "  -r <frame rate>  : Frame rate to use.  Defaults to 48000 Hz\n"
         "  -b <bits/sample> : Bits per sample to use.  Defaults to 16\n"
         "  -c <channels>    : Number of channels to use.  Defaults to 2\n"
         "  -a <active>      : Active channel (choose from 0 to <channels> - 1 inclusive).\n"
         "                     Defaults to all channels active (not set).\n");
  printf("\nValid command are\n");
  printf("info   : Fetches capability and status info for the specified stream\n");
  printf("mute   : Mute the specified stream\n");
  printf("unmute : Unmute the specified stream\n");
  printf("agc    : Params : (on|off)\n");
  printf("         Enable or disable AGC for the specified input stream.\n");
  printf("gain   : Params : <db_gain>\n");
  printf("         Set the gain of the stream to the specified level\n");
  printf("pmon   : Params : [<duration>]\n"
         "         Monitor the plug state of the specified stream for the\n"
         "         specified amount of time.  Duration defaults to %.1fs and is\n"
         "         floored at %u mSec\n",
         DEFAULT_PLUG_MONITOR_DURATION,
         static_cast<int>(MIN_PLUG_MONITOR_DURATION * 1000));
  printf("tone   : Params : [<freq>] [<duration>]\n"
         "         Play a sinusoidal tone of the specified frequency for the\n"
         "         specified duration.  Frequency is clamped on the range\n"
         "         [%.1f, %.1f] Hz.  Duration is given in seconds and floored\n"
         "         at %d mSec.  Default is %.1f Hz for %.1f seconds\n",
          MIN_TONE_FREQ,
          MAX_TONE_FREQ,
          static_cast<int>(MIN_TONE_DURATION * 1000),
          DEFAULT_TONE_FREQ,
          DEFAULT_TONE_DURATION);
  printf("play   : Params : <file>\n");
  printf("         Play the specified WAV file on the selected output.\n");
  printf("record : Params : <file> [duration]\n"
         "         Record to the specified WAV file from the selected input.\n"
         "         Duration defaults to %.1f seconds if unspecified.\n",
         DEFAULT_RECORD_DURATION);
  // clang-format on
}

void dump_format_range(size_t ndx, const audio_stream_format_range_t& range) {
  printf("[%2zu] Sample Format :", ndx);

  struct {
    audio_sample_format_t flag;
    const char* name;
  } SF_FLAG_LUT[] = {
      {AUDIO_SAMPLE_FORMAT_FLAG_UNSIGNED, "Unsigned"},
      {AUDIO_SAMPLE_FORMAT_FLAG_INVERT_ENDIAN, "Inv Endian"},
  };

  for (const auto& sf : SF_FLAG_LUT) {
    if (range.sample_formats & sf.flag) {
      printf(" %s", sf.name);
    }
  }

  struct {
    audio_sample_format_t flag;
    const char* name;
  } SF_FORMAT_LUT[] = {
      {AUDIO_SAMPLE_FORMAT_BITSTREAM, "Bitstream"},
      {AUDIO_SAMPLE_FORMAT_8BIT, "8"},
      {AUDIO_SAMPLE_FORMAT_16BIT, "16"},
      {AUDIO_SAMPLE_FORMAT_20BIT_PACKED, "20-packed"},
      {AUDIO_SAMPLE_FORMAT_24BIT_PACKED, "24-packed"},
      {AUDIO_SAMPLE_FORMAT_20BIT_IN32, "20-in-32"},
      {AUDIO_SAMPLE_FORMAT_24BIT_IN32, "24-in-32"},
      {AUDIO_SAMPLE_FORMAT_32BIT, "32"},
      {AUDIO_SAMPLE_FORMAT_32BIT_FLOAT, "Float 32"},
  };

  bool first = true;
  printf(" [");
  for (const auto& sf : SF_FORMAT_LUT) {
    if (range.sample_formats & sf.flag) {
      printf("%s%s", first ? "" : ", ", sf.name);
      first = false;
    }
  }
  printf("]\n");

  printf("     Channel Count : [%u, %u]\n", range.min_channels, range.max_channels);
  printf("     Frame Rates   :");
  if (range.flags & ASF_RANGE_FLAG_FPS_CONTINUOUS) {
    printf(" [%u, %u] Hz continuous\n", range.min_frames_per_second, range.max_frames_per_second);
  } else {
    audio::utils::FrameRateEnumerator enumerator(range);

    first = true;
    for (uint32_t rate : enumerator) {
      printf("%s%u", first ? " " : ", ", rate);
      first = false;
    }

    printf(" Hz\n");
  }
}

static void FixupStringRequest(audio_stream_cmd_get_string_resp_t* resp, zx_status_t res) {
  if (res != ZX_OK) {
    snprintf(reinterpret_cast<char*>(resp->str), sizeof(resp->str), "<err %d>", res);
    return;
  }

  if (resp->strlen > sizeof(resp->str)) {
    snprintf(reinterpret_cast<char*>(resp->str), sizeof(resp->str), "<bad strllen %u>",
             resp->strlen);
    return;
  }

  // We are going to display this string using ASCII, but it is encoded using
  // UTF8.  Go over the string and replace unprintable characters with
  // something else.  Also replace embedded nulls with a space.  Finally,
  // ensure that the string is null terminated.
  uint32_t len = fbl::min<uint32_t>(sizeof(resp->str) - 1, resp->strlen);
  uint32_t i;
  for (i = 0; i < len; ++i) {
    if (resp->str[i] == 0) {
      resp->str[i] = ' ';
    } else if (!isprint(resp->str[i])) {
      resp->str[i] = '?';
    }
  }

  resp->str[i] = 0;
}

zx_status_t dump_stream_info(const audio::utils::AudioDeviceStream& stream) {
  zx_status_t res;
  printf("Info for audio %s at \"%s\"\n", stream.input() ? "input" : "output", stream.name());

  // Grab and display some of the interesting properties of the device,
  // including its unique ID, its manufacturer name, and its product name.
  audio_stream_cmd_get_unique_id_resp_t uid_resp;
  res = stream.GetUniqueId(&uid_resp);
  if (res != ZX_OK) {
    printf("Failed to fetch unique ID! (res %d)\n", res);
    return res;
  }

  const auto& uid = uid_resp.unique_id.data;
  static_assert(sizeof(uid) == 16, "Unique ID is not 16 bytes long!\n");
  printf("  Unique ID    : %02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x\n",
         uid[0], uid[1], uid[2], uid[3], uid[4], uid[5], uid[6], uid[7], uid[8], uid[9], uid[10],
         uid[11], uid[12], uid[13], uid[14], uid[15]);

  audio_stream_cmd_get_string_resp_t str_resp;
  res = stream.GetString(AUDIO_STREAM_STR_ID_MANUFACTURER, &str_resp);
  FixupStringRequest(&str_resp, res);
  printf("  Manufacturer : %s\n", str_resp.str);

  res = stream.GetString(AUDIO_STREAM_STR_ID_PRODUCT, &str_resp);
  FixupStringRequest(&str_resp, res);
  printf("  Product      : %s\n", str_resp.str);

  // Fetch and print the current gain settings for this audio stream.
  audio_stream_cmd_get_gain_resp gain_state;
  res = stream.GetGain(&gain_state);
  if (res != ZX_OK) {
    printf("Failed to fetch gain information! (res %d)\n", res);
    return res;
  }

  printf("  Current Gain : %.2f dB (%smuted%s)\n", gain_state.cur_gain,
         gain_state.cur_mute ? "" : "un",
         gain_state.can_agc ? (gain_state.cur_agc ? ", AGC on" : ", AGC off") : "");
  printf("  Gain Caps    : ");
  if ((gain_state.min_gain == gain_state.max_gain) && (gain_state.min_gain == 0.0f)) {
    printf("fixed 0 dB gain");
  } else if (gain_state.gain_step == 0.0f) {
    printf("gain range [%.2f, %.2f] dB (continuous)", gain_state.min_gain, gain_state.max_gain);
  } else {
    printf("gain range [%.2f, %.2f] in %.2f dB steps", gain_state.min_gain, gain_state.max_gain,
           gain_state.gain_step);
  }
  printf("; %s mute", gain_state.can_mute ? "can" : "cannot");
  printf("; %s AGC\n", gain_state.can_agc ? "can" : "cannot");

  // Fetch and print the current pluged/unplugged state for this audio stream.
  audio_stream_cmd_plug_detect_resp plug_state;
  res = stream.GetPlugState(&plug_state);
  if (res != ZX_OK) {
    printf("Failed to fetch plug state information! (res %d)\n", res);
    return res;
  }

  printf("  Plug State   : %splugged\n", plug_state.flags & AUDIO_PDNF_PLUGGED ? "" : "un");
  printf("  Plug Time    : %lu\n", plug_state.plug_state_time);
  printf("  PD Caps      : %s\n",
         (plug_state.flags & AUDIO_PDNF_HARDWIRED)
             ? "hardwired"
             : ((plug_state.flags & AUDIO_PDNF_CAN_NOTIFY) ? "dynamic (async)"
                                                           : "dynamic (synchronous)"));

  // Fetch and print the currently supported audio formats for this audio stream.
  fbl::Vector<audio_stream_format_range_t> fmts;
  res = stream.GetSupportedFormats(&fmts);
  if (res != ZX_OK) {
    printf("Failed to fetch supported formats! (res %d)\n", res);
    return res;
  }

  printf("\nStream supports %zu format range%s\n", fmts.size(), fmts.size() == 1 ? "" : "s");
  for (size_t i = 0; i < fmts.size(); ++i)
    dump_format_range(i, fmts[i]);

  return ZX_OK;
}

int main(int argc, const char** argv) {
  bool input = false;
  uint32_t dev_id = 0;
  uint32_t frame_rate = DEFAULT_FRAME_RATE;
  uint32_t bits_per_sample = DEFAULT_BITS_PER_SAMPLE;
  uint32_t channels = DEFAULT_CHANNELS;
  uint32_t active = DEFAULT_ACTIVE_CHANNELS;
  Command cmd = Command::INVALID;
  auto print_usage = fbl::MakeAutoCall([prog_name = argv[0]]() { usage(prog_name); });
  int arg = 1;

  if (arg >= argc)
    return -1;

  struct {
    const char* name;
    const char* tag;
    uint32_t* val;
  } UINT_OPTIONS[] = {
      // clang-format off
    { .name = "-d", .tag = "device ID",   .val = &dev_id },
    { .name = "-r", .tag = "frame rate",  .val = &frame_rate },
    { .name = "-b", .tag = "bits/sample", .val = &bits_per_sample },
    { .name = "-c", .tag = "channels",    .val = &channels },
    { .name = "-a", .tag = "active",      .val = &active },
      // clang-format on
  };

  static const struct {
    const char* name;
    Command cmd;
    bool force_out;
    bool force_in;
  } COMMANDS[] = {
      // clang-format off
    { "info",   Command::INFO,          false, false },
    { "mute",   Command::MUTE,          false, false },
    { "unmute", Command::UNMUTE,        false, false },
    { "agc",    Command::AGC,           false, true  },
    { "gain",   Command::GAIN,          false, false },
    { "pmon",   Command::PLUG_MONITOR,  false, false },
    { "tone",   Command::TONE,          true,  false },
    { "play",   Command::PLAY,          true,  false },
    { "record", Command::RECORD,        false, true  },
      // clang-format on
  };

  while (arg < argc) {
    // Check to see if this is an integer option
    bool parsed_option = false;
    for (const auto& o : UINT_OPTIONS) {
      if (!strcmp(o.name, argv[arg])) {
        // Looks like this is an integer argument we care about.
        // Attempt to parse it.
        if (++arg >= argc)
          return -1;
        if (sscanf(argv[arg], "%u", o.val) != 1) {
          printf("Failed to parse %s option, \"%s\"\n", o.tag, argv[arg]);
          return -1;
        }
        ++arg;
        parsed_option = true;
        break;
      }
    }

    // If we successfully parse an integer option, continue on to the next
    // argument (if any).
    if (parsed_option)
      continue;

    // Was this the device type flag?
    if (!strcmp("-t", argv[arg])) {
      if (++arg >= argc)
        return -1;
      if (!strcmp("input", argv[arg])) {
        input = true;
      } else if (!strcmp("output", argv[arg])) {
        input = false;
      } else {
        printf("Invalid input/output specifier \"%s\".\n", argv[arg]);
        return -1;
      }
      ++arg;
      continue;
    }

    // Well, this didn't look like an option we understand, so it must be a
    // command.  Attempt to figure out what command it was.
    for (const auto& entry : COMMANDS) {
      if (!strcmp(entry.name, argv[arg])) {
        cmd = entry.cmd;
        parsed_option = true;
        arg++;

        if (entry.force_out)
          input = false;
        if (entry.force_in)
          input = true;

        break;
      }
    }

    if (!parsed_option) {
      printf("Failed to parse command ID \"%s\"\n", argv[arg]);
      return -1;
    }

    break;
  }

  if (cmd == Command::INVALID) {
    printf("Failed to find valid command ID.\n");
    return -1;
  }

  audio_sample_format_t sample_format;
  switch (bits_per_sample) {
    case 8:
      sample_format = AUDIO_SAMPLE_FORMAT_UNSIGNED_8BIT;
      break;
    case 16:
      sample_format = AUDIO_SAMPLE_FORMAT_16BIT;
      break;
    case 20:
      sample_format = AUDIO_SAMPLE_FORMAT_20BIT_IN32;
      break;
    case 24:
      sample_format = AUDIO_SAMPLE_FORMAT_24BIT_IN32;
      break;
    case 32:
      sample_format = AUDIO_SAMPLE_FORMAT_32BIT;
      break;
    default:
      printf("Unsupported number of bits per sample (%u)\n", bits_per_sample);
      return -1;
  }

  float tone_freq = 440.0;
  float duration;
  const char* wav_filename = nullptr;
  float target_gain = -100.0;
  bool enb_agc = false;

  // Parse any additional arguments
  switch (cmd) {
    case Command::GAIN:
      if (arg >= argc)
        return -1;
      if (sscanf(argv[arg], "%f", &target_gain) != 1) {
        printf("Failed to parse gain \"%s\"\n", argv[arg]);
        return -1;
      }
      arg++;
      break;

    case Command::AGC:
      if (arg >= argc)
        return -1;
      if (strcasecmp(argv[arg], "on") == 0) {
        enb_agc = true;
      } else if (strcasecmp(argv[arg], "off") == 0) {
        enb_agc = false;
      } else {
        printf("Failed to parse agc setting \"%s\"\n", argv[arg]);
        return -1;
      }
      arg++;
      break;

    case Command::PLUG_MONITOR:
      duration = DEFAULT_PLUG_MONITOR_DURATION;
      if (arg < argc) {
        if (sscanf(argv[arg], "%f", &duration) != 1) {
          printf("Failed to parse plug monitor duration \"%s\"\n", argv[arg]);
          return -1;
        }
        arg++;
        duration = fbl::max(duration, MIN_PLUG_MONITOR_DURATION);
      }
      break;

    case Command::TONE:
      duration = DEFAULT_TONE_DURATION;
      if (arg < argc) {
        if (sscanf(argv[arg], "%f", &tone_freq) != 1) {
          printf("Failed to parse tone frequency \"%s\"\n", argv[arg]);
          return -1;
        }
        arg++;

        if (arg < argc) {
          if (sscanf(argv[arg], "%f", &duration) != 1) {
            printf("Failed to parse tone duration \"%s\"\n", argv[arg]);
            return -1;
          }
          arg++;
        }

        tone_freq = fbl::clamp(tone_freq, 15.0f, 20000.0f);
        duration = fbl::max(duration, MIN_TONE_DURATION);
      }
      break;

    case Command::PLAY:
    case Command::RECORD:
      if (arg >= argc)
        return -1;
      wav_filename = argv[arg];
      arg++;

      if (cmd == Command::RECORD) {
        duration = DEFAULT_RECORD_DURATION;
        if (arg < argc) {
          if (sscanf(argv[arg], "%f", &duration) != 1) {
            printf("Failed to parse record duration \"%s\"\n", argv[arg]);
            return -1;
          }
          arg++;
        }
      }

      break;

    default:
      break;
  }

  if (arg != argc) {
    printf("Invalid number of arguments.\n");
    return -1;
  }

  // Argument parsing is done, we can cancel the usage dump.
  print_usage.cancel();

  // Open the selected stream.
  std::unique_ptr<audio::utils::AudioDeviceStream> stream;
  if (input)
    stream = audio::utils::AudioInput::Create(dev_id);
  else
    stream = audio::utils::AudioOutput::Create(dev_id);
  if (stream == nullptr) {
    printf("Out of memory!\n");
    return ZX_ERR_NO_MEMORY;
  }

  // No need to log in the case of failure.  Open has already done so.
  zx_status_t res = stream->Open();
  if (res != ZX_OK)
    return res;

  // Execute the chosen command.
  switch (cmd) {
    case Command::INFO:
      return dump_stream_info(*stream);
    case Command::MUTE:
      return stream->SetMute(true);
    case Command::UNMUTE:
      return stream->SetMute(false);
    case Command::GAIN:
      return stream->SetGain(target_gain);
    case Command::AGC:
      return stream->SetAgc(enb_agc);
    case Command::PLUG_MONITOR:
      return stream->PlugMonitor(duration, nullptr);

    case Command::TONE: {
      if (stream->input()) {
        printf("The \"tone\" command can only be used on output streams.\n");
        return -1;
      }

      SineSource sine_source;
      res = sine_source.Init(tone_freq, 1.0, duration, frame_rate, channels, active, sample_format);
      if (res != ZX_OK) {
        printf("Failed to initialize sine wav generator (res %d)\n", res);
        return res;
      }

      printf("Playing %.2f Hz tone for %.2f seconds\n", tone_freq, duration);
      return static_cast<audio::utils::AudioOutput*>(stream.get())->Play(sine_source);
    }

    case Command::PLAY: {
      if (stream->input()) {
        printf("The \"play\" command can only be used on output streams.\n");
        return -1;
      }

      WAVSource wav_source;
      res = wav_source.Initialize(wav_filename);
      if (res != ZX_OK)
        return res;

      return static_cast<audio::utils::AudioOutput*>(stream.get())->Play(wav_source);
    }

    case Command::RECORD: {
      if (!stream->input()) {
        printf("The \"record\" command can only be used on input streams.\n");
        return -1;
      }

      res = stream->SetFormat(frame_rate, static_cast<uint16_t>(channels), sample_format);
      if (res != ZX_OK) {
        printf("Failed to set format (rate %u, chan %u, fmt 0x%08x, res %d)\n", frame_rate,
               channels, sample_format, res);
        return -1;
      }

      WAVSink wav_sink;
      res = wav_sink.Initialize(wav_filename);
      if (res != ZX_OK)
        return res;

      return static_cast<audio::utils::AudioInput*>(stream.get())->Record(wav_sink, duration);
    }

    default:
      ZX_DEBUG_ASSERT(false);
      return -1;
  }
}
