// Copyright (c) 2012 The Chromium OS 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 "cras_dsp_pipeline.h"

#include <gtest/gtest.h>

#include "cras_config.h"
#include "cras_dsp_module.h"

#define MAX_MODULES 10
#define MAX_MOCK_PORTS 30
#define FILENAME_TEMPLATE "DspIniTest.XXXXXX"

static void fill_test_data(int16_t* data, size_t size) {
  for (size_t i = 0; i < size; i++)
    data[i] = i;
}

static void verify_processed_data(int16_t* data, size_t size, int times) {
  /* Each time the audio data flow through the mock plugin, the data
   * will be multiplied by 2 in module->run() below, so if there are n
   * plugins, the data will be multiplied by (1 << n). */
  int multiples = (1 << times);
  for (size_t i = 0; i < size; i++) {
    EXPECT_EQ(i * multiples, data[i]);
    if ((int16_t)i * multiples != data[i])
      return;
  }
}

struct data {
  const char* title;
  int nr_ports;
  port_direction port_dir[MAX_MOCK_PORTS];
  int nr_in_audio;
  int nr_in_control;
  int nr_out_audio;
  int nr_out_control;
  int in_audio[MAX_MOCK_PORTS];
  int in_control[MAX_MOCK_PORTS];
  int out_audio[MAX_MOCK_PORTS];
  int out_control[MAX_MOCK_PORTS];
  int properties;

  int instantiate_called;
  int sample_rate;

  int connect_port_called[MAX_MOCK_PORTS];
  float* data_location[MAX_MOCK_PORTS];

  int run_called;
  float input[MAX_MOCK_PORTS];
  float output[MAX_MOCK_PORTS];

  int sample_count;

  int get_delay_called;
  int deinstantiate_called;
  int free_module_called;
  int get_properties_called;
};

static int instantiate(struct dsp_module* module, unsigned long sample_rate) {
  struct data* data = (struct data*)module->data;
  data->instantiate_called++;
  data->sample_rate = sample_rate;
  return 0;
}

static void connect_port(struct dsp_module* module,
                         unsigned long port,
                         float* data_location) {
  struct data* data = (struct data*)module->data;
  data->connect_port_called[port]++;
  data->data_location[port] = data_location;
}

static int get_delay(struct dsp_module* module) {
  struct data* data = (struct data*)module->data;
  data->get_delay_called++;

  /* If the module title is "mN", then use N as the delay. */
  int delay = 0;
  sscanf(data->title, "m%d", &delay);
  return delay;
}

static void run(struct dsp_module* module, unsigned long sample_count) {
  struct data* data = (struct data*)module->data;
  data->run_called++;
  data->sample_count = sample_count;

  for (int i = 0; i < data->nr_ports; i++) {
    if (data->port_dir[i] == PORT_INPUT)
      data->input[i] = *data->data_location[i];
  }

  /* copy the control port data */
  for (int i = 0; i < std::min(data->nr_in_control, data->nr_out_control);
       i++) {
    int from = data->in_control[i];
    int to = data->out_control[i];
    data->data_location[to][0] = data->data_location[from][0];
  }

  /* multiply the audio port data by 2 */
  for (int i = 0; i < std::min(data->nr_in_audio, data->nr_out_audio); i++) {
    int from = data->in_audio[i];
    int to = data->out_audio[i];
    for (unsigned int j = 0; j < sample_count; j++)
      data->data_location[to][j] = data->data_location[from][j] * 2;
  }
}

static void deinstantiate(struct dsp_module* module) {
  struct data* data = (struct data*)module->data;
  data->deinstantiate_called++;
}

static void free_module(struct dsp_module* module) {
  struct data* data = (struct data*)module->data;
  data->free_module_called++;
}

static void really_free_module(struct dsp_module* module) {
  struct data* data = (struct data*)module->data;
  free(data);
  free(module);
}

static int get_properties(struct dsp_module* module) {
  struct data* data = (struct data*)module->data;
  data->get_properties_called++;
  return data->properties;
}
static void dump(struct dsp_module* module, struct dumper* d) {}

static struct dsp_module* create_mock_module(struct plugin* plugin) {
  struct data* data;
  struct dsp_module* module;

  data = (struct data*)calloc(1, sizeof(struct data));
  data->title = plugin->title;
  data->nr_ports = ARRAY_COUNT(&plugin->ports);
  for (int i = 0; i < data->nr_ports; i++) {
    struct port* port = ARRAY_ELEMENT(&plugin->ports, i);
    data->port_dir[i] = port->direction;

    if (port->direction == PORT_INPUT) {
      if (port->type == PORT_AUDIO)
        data->in_audio[data->nr_in_audio++] = i;
      else
        data->in_control[data->nr_in_control++] = i;
    } else {
      if (port->type == PORT_AUDIO)
        data->out_audio[data->nr_out_audio++] = i;
      else
        data->out_control[data->nr_out_control++] = i;
    }
  }
  if (strcmp(plugin->label, "inplace_broken") == 0) {
    data->properties = MODULE_INPLACE_BROKEN;
  } else {
    data->properties = 0;
  }

  module = (struct dsp_module*)calloc(1, sizeof(struct dsp_module));
  module->data = data;
  module->instantiate = &instantiate;
  module->connect_port = &connect_port;
  module->get_delay = &get_delay;
  module->run = &run;
  module->deinstantiate = &deinstantiate;
  module->free_module = &free_module;
  module->get_properties = &get_properties;
  module->dump = &dump;
  return module;
}

static struct dsp_module* modules[MAX_MODULES];
static struct dsp_module* cras_dsp_module_set_sink_ext_module_val;
static int num_modules;
static struct dsp_module* find_module(const char* name) {
  for (int i = 0; i < num_modules; i++) {
    struct data* data = (struct data*)modules[i]->data;
    if (strcmp(name, data->title) == 0)
      return modules[i];
  }
  return NULL;
}

extern "C" {
struct dsp_module* cras_dsp_module_load_ladspa(struct plugin* plugin) {
  return NULL;
}
struct dsp_module* cras_dsp_module_load_builtin(struct plugin* plugin) {
  struct dsp_module* module = create_mock_module(plugin);
  modules[num_modules++] = module;
  return module;
}
void cras_dsp_module_set_sink_ext_module(struct dsp_module* module,
                                         struct ext_dsp_module* ext_module) {
  cras_dsp_module_set_sink_ext_module_val = module;
}
}

namespace {

class DspPipelineTestSuite : public testing::Test {
 protected:
  virtual void SetUp() {
    num_modules = 0;
    strcpy(filename, FILENAME_TEMPLATE);
    int fd = mkstemp(filename);
    fp = fdopen(fd, "w");
  }

  virtual void TearDown() {
    CloseFile();
    unlink(filename);
  }

  virtual void CloseFile() {
    if (fp) {
      fclose(fp);
      fp = NULL;
    }
  }

  char filename[sizeof(FILENAME_TEMPLATE) + 1];
  FILE* fp;
  struct ext_dsp_module ext_mod;
};

TEST_F(DspPipelineTestSuite, Simple) {
  const char* content =
      "[M1]\n"
      "library=builtin\n"
      "label=source\n"
      "purpose=capture\n"
      "output_0={audio}\n"
      "output_1=<control>\n"
      "input_2=3.0\n"
      "[M2]\n"
      "library=builtin\n"
      "label=sink\n"
      "purpose=capture\n"
      "input_0=<control>\n"
      "input_1={audio}\n"
      "\n";
  fprintf(fp, "%s", content);
  CloseFile();

  struct cras_expr_env env = CRAS_EXPR_ENV_INIT;
  struct ini* ini = cras_dsp_ini_create(filename);
  ASSERT_TRUE(ini);
  struct pipeline* p = cras_dsp_pipeline_create(ini, &env, "capture");
  ASSERT_TRUE(p);
  ASSERT_EQ(0, cras_dsp_pipeline_load(p));

  ASSERT_EQ(2, num_modules);
  struct dsp_module* m1 = find_module("m1");
  struct dsp_module* m2 = find_module("m2");
  ASSERT_TRUE(m1);
  ASSERT_TRUE(m2);

  ASSERT_EQ(1, cras_dsp_pipeline_get_num_input_channels(p));
  ASSERT_EQ(0, cras_dsp_pipeline_instantiate(p, 48000));

  struct data* d1 = (struct data*)m1->data;
  struct data* d2 = (struct data*)m2->data;

  /* check m1 */
  ASSERT_STREQ("m1", d1->title);
  ASSERT_EQ(3, d1->nr_ports);
  ASSERT_EQ(PORT_OUTPUT, d1->port_dir[0]);
  ASSERT_EQ(PORT_OUTPUT, d1->port_dir[1]);
  ASSERT_EQ(PORT_INPUT, d1->port_dir[2]);
  ASSERT_EQ(1, d1->instantiate_called);
  ASSERT_EQ(1, d1->get_delay_called);
  ASSERT_EQ(48000, d1->sample_rate);
  ASSERT_EQ(1, d1->connect_port_called[0]);
  ASSERT_EQ(1, d1->connect_port_called[1]);
  ASSERT_EQ(1, d1->connect_port_called[2]);
  ASSERT_TRUE(d1->data_location[0]);
  ASSERT_TRUE(d1->data_location[1]);
  ASSERT_TRUE(d1->data_location[2]);
  ASSERT_EQ(0, d1->run_called);
  ASSERT_EQ(0, d1->deinstantiate_called);
  ASSERT_EQ(0, d1->free_module_called);
  ASSERT_EQ(1, d1->get_properties_called);

  /* check m2 */
  ASSERT_STREQ("m2", d2->title);
  ASSERT_EQ(2, d2->nr_ports);
  ASSERT_EQ(PORT_INPUT, d2->port_dir[0]);
  ASSERT_EQ(PORT_INPUT, d2->port_dir[1]);
  ASSERT_EQ(1, d2->instantiate_called);
  ASSERT_EQ(1, d2->get_delay_called);
  ASSERT_EQ(48000, d2->sample_rate);
  ASSERT_EQ(1, d2->connect_port_called[0]);
  ASSERT_EQ(1, d2->connect_port_called[1]);
  ASSERT_TRUE(d2->data_location[0]);
  ASSERT_TRUE(d2->data_location[1]);
  ASSERT_EQ(0, d2->run_called);
  ASSERT_EQ(0, d2->deinstantiate_called);
  ASSERT_EQ(0, d2->free_module_called);
  ASSERT_EQ(1, d2->get_properties_called);

  /* check the buffer is shared */
  ASSERT_EQ(d1->data_location[0], d2->data_location[1]);
  ASSERT_EQ(d1->data_location[1], d2->data_location[0]);
  ASSERT_EQ(1, cras_dsp_pipeline_get_peak_audio_buffers(p));

  d1->data_location[0][0] = 100;
  cras_dsp_pipeline_run(p, DSP_BUFFER_SIZE);
  ASSERT_EQ(1, d1->run_called);
  ASSERT_EQ(1, d2->run_called);
  ASSERT_EQ(3, d1->input[2]);
  ASSERT_EQ(3, d2->input[0]);
  ASSERT_EQ(100, d2->input[1]);

  d1->data_location[0][0] = 1000;
  cras_dsp_pipeline_run(p, DSP_BUFFER_SIZE);
  ASSERT_EQ(2, d1->run_called);
  ASSERT_EQ(2, d2->run_called);
  ASSERT_EQ(3, d1->input[2]);
  ASSERT_EQ(3, d2->input[0]);
  ASSERT_EQ(1000, d2->input[1]);

  /* Expect the sink module "m2" is set. */
  cras_dsp_pipeline_set_sink_ext_module(p, &ext_mod);
  struct data* d = (struct data*)cras_dsp_module_set_sink_ext_module_val->data;
  ASSERT_STREQ("m2", d->title);

  cras_dsp_pipeline_deinstantiate(p);
  ASSERT_EQ(1, d1->deinstantiate_called);
  ASSERT_EQ(1, d2->deinstantiate_called);

  cras_dsp_pipeline_free(p);
  ASSERT_EQ(1, d1->free_module_called);
  ASSERT_EQ(1, d2->free_module_called);

  cras_dsp_ini_free(ini);
  cras_expr_env_free(&env);

  really_free_module(m1);
  really_free_module(m2);
}

TEST_F(DspPipelineTestSuite, Complex) {
  /*
   *                   / --(b)-- 2 --(c)-- \
   *   0 ==(a0, a1)== 1                     4 ==(f0,f1)== 5
   *                   \ --(d)-- 3 --(e)-- /
   *
   *
   *                     --(g)-- 6 --(h)--
   */

  const char* content =
      "[M6]\n"
      "library=builtin\n"
      "label=foo\n"
      "input_0={g}\n"
      "output_1={h}\n"
      "[M5]\n"
      "library=builtin\n"
      "label=sink\n"
      "purpose=playback\n"
      "input_0={f0}\n"
      "input_1={f1}\n"
      "[M4]\n"
      "library=builtin\n"
      "label=foo\n"
      "disable=(equal? output_device \"HDMI\")\n"
      "input_0=3.14\n"
      "input_1={c}\n"
      "output_2={f0}\n"
      "input_3={e}\n"
      "output_4={f1}\n"
      "[M3]\n"
      "library=builtin\n"
      "label=foo\n"
      "input_0={d}\n"
      "output_1={e}\n"
      "[M2]\n"
      "library=builtin\n"
      "label=inplace_broken\n"
      "input_0={b}\n"
      "output_1={c}\n"
      "[M1]\n"
      "library=builtin\n"
      "label=foo\n"
      "disable=(equal? output_device \"USB\")\n"
      "input_0={a0}\n"
      "input_1={a1}\n"
      "output_2={b}\n"
      "output_3={d}\n"
      "[M0]\n"
      "library=builtin\n"
      "label=source\n"
      "purpose=playback\n"
      "output_0={a0}\n"
      "output_1={a1}\n";
  fprintf(fp, "%s", content);
  CloseFile();

  struct cras_expr_env env = CRAS_EXPR_ENV_INIT;
  cras_expr_env_install_builtins(&env);
  cras_expr_env_set_variable_string(&env, "output_device", "HDMI");
  cras_expr_env_set_variable_boolean(&env, "swap_lr_disabled", 1);

  struct ini* ini = cras_dsp_ini_create(filename);
  ASSERT_TRUE(ini);
  struct pipeline* p = cras_dsp_pipeline_create(ini, &env, "playback");
  ASSERT_TRUE(p);
  ASSERT_EQ(0, cras_dsp_pipeline_load(p));

  ASSERT_EQ(5, num_modules); /* one not connected, one disabled */
  struct dsp_module* m0 = find_module("m0");
  struct dsp_module* m1 = find_module("m1");
  struct dsp_module* m2 = find_module("m2");
  struct dsp_module* m3 = find_module("m3");
  struct dsp_module* m5 = find_module("m5");

  ASSERT_TRUE(m0);
  ASSERT_TRUE(m1);
  ASSERT_TRUE(m2);
  ASSERT_TRUE(m3);
  ASSERT_FALSE(find_module("m4"));
  ASSERT_TRUE(m5);
  ASSERT_FALSE(find_module("m6"));

  ASSERT_EQ(2, cras_dsp_pipeline_get_num_input_channels(p));
  ASSERT_EQ(0, cras_dsp_pipeline_instantiate(p, 48000));

  struct data* d0 = (struct data*)m0->data;
  struct data* d1 = (struct data*)m1->data;
  struct data* d2 = (struct data*)m2->data;
  struct data* d3 = (struct data*)m3->data;
  struct data* d5 = (struct data*)m5->data;

  /*
   *                   / --(b)-- 2 --(c)-- \
   *   0 ==(a0, a1)== 1                     4 ==(f0,f1)== 5
   *                   \ --(d)-- 3 --(e)-- /
   *
   *
   *                     --(g)-- 6 --(h)--
   */

  ASSERT_EQ(d0->data_location[0], d1->data_location[0]);
  ASSERT_EQ(d0->data_location[1], d1->data_location[1]);
  ASSERT_EQ(d1->data_location[2], d2->data_location[0]);
  ASSERT_EQ(d1->data_location[3], d3->data_location[0]);
  ASSERT_NE(d2->data_location[0], d2->data_location[1]); /* inplace-broken */
  ASSERT_EQ(d2->data_location[1], d5->data_location[0]); /* m4 is disabled */
  ASSERT_EQ(d3->data_location[1], d5->data_location[1]);

  /* need 3 buffers because m2 has inplace-broken flag */
  ASSERT_EQ(3, cras_dsp_pipeline_get_peak_audio_buffers(p));

  int16_t* samples = new int16_t[DSP_BUFFER_SIZE];
  fill_test_data(samples, DSP_BUFFER_SIZE);
  cras_dsp_pipeline_apply(p, (uint8_t*)samples, SND_PCM_FORMAT_S16_LE, 100);
  /* the data flow through 2 plugins because m4 is disabled. */
  verify_processed_data(samples, 100, 2);
  delete[] samples;

  ASSERT_EQ(1, d1->run_called);
  ASSERT_EQ(1, d3->run_called);

  /* check m5 */
  ASSERT_EQ(1, d5->run_called);
  ASSERT_EQ(100, d5->sample_count);

  /* Expect the sink module "m5" is set. */
  cras_dsp_pipeline_set_sink_ext_module(p, &ext_mod);
  struct data* d = (struct data*)cras_dsp_module_set_sink_ext_module_val->data;
  ASSERT_STREQ("m5", d->title);

  /* re-instantiate */
  ASSERT_EQ(1, d5->instantiate_called);
  ASSERT_EQ(1, d5->get_delay_called);
  ASSERT_EQ(1 + 3 + 5, cras_dsp_pipeline_get_delay(p));

  cras_dsp_pipeline_deinstantiate(p);
  cras_dsp_pipeline_instantiate(p, 44100);

  ASSERT_EQ(1, d5->deinstantiate_called);
  ASSERT_EQ(2, d5->instantiate_called);
  ASSERT_EQ(2, d5->get_delay_called);
  ASSERT_EQ(1 + 3 + 5, cras_dsp_pipeline_get_delay(p));
  ASSERT_EQ(0, d5->free_module_called);
  ASSERT_EQ(44100, d5->sample_rate);
  ASSERT_EQ(2, d5->connect_port_called[0]);
  ASSERT_EQ(2, d5->connect_port_called[1]);

  cras_dsp_pipeline_free(p);
  cras_dsp_ini_free(ini);
  cras_expr_env_free(&env);

  really_free_module(m0);
  really_free_module(m1);
  really_free_module(m2);
  really_free_module(m3);
  really_free_module(m5);
}

}  //  namespace

int main(int argc, char** argv) {
  ::testing::InitGoogleTest(&argc, argv);
  return RUN_ALL_TESTS();
}
