/* Copyright (c) 2018 The Chromium 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 "api/audio/echo_canceller3_factory.h"
#include "modules/audio_processing/aec_dump/aec_dump_factory.h"
#include "modules/audio_processing/include/aec_dump.h"
#include "modules/audio_processing/include/audio_processing.h"
#include "modules/include/module_common_types.h"
#include "rtc_base/task_queue.h"

extern "C" {
#include "webrtc_apm.h"

int convert_to_aec3_config(
		const struct aec_config *config,
		webrtc::EchoCanceller3Config *aec3_config)
{
	aec3_config->delay = {
		config->delay.default_delay,
		config->delay.down_sampling_factor,
		config->delay.num_filters,
		config->delay.api_call_jitter_blocks,
		config->delay.min_echo_path_delay_blocks,
		config->delay.delay_headroom_blocks,
		config->delay.hysteresis_limit_1_blocks,
		config->delay.hysteresis_limit_2_blocks,
		config->delay.skew_hysteresis_blocks
	};
	aec3_config->filter.main = {
		config->filter.main.length_blocks,
		config->filter.main.leakage_converged,
		config->filter.main.leakage_diverged,
		config->filter.main.error_floor,
		config->filter.main.noise_gate
	};
	aec3_config->filter.shadow = {
		config->filter.shadow.length_blocks,
		config->filter.shadow.rate,
		config->filter.shadow.noise_gate
	};
	aec3_config->filter.main_initial = {
		config->filter.main_initial.length_blocks,
		config->filter.main_initial.leakage_converged,
		config->filter.main_initial.leakage_diverged,
		config->filter.main_initial.error_floor,
		config->filter.main_initial.noise_gate
	};
	aec3_config->filter.shadow_initial = {
		config->filter.shadow_initial.length_blocks,
		config->filter.shadow_initial.rate,
		config->filter.shadow_initial.noise_gate
	};
	aec3_config->filter.config_change_duration_blocks =
		config->filter.config_change_duration_blocks;
	aec3_config->erle = {
		config->erle.min,
		config->erle.max_l,
		config->erle.max_h,
	};
	aec3_config->ep_strength = {
		config->ep_strength.lf,
		config->ep_strength.mf,
		config->ep_strength.hf,
		config->ep_strength.default_len,
		static_cast<bool>(config->ep_strength.echo_can_saturate),
		static_cast<bool>(config->ep_strength.bounded_erl)
	};

	aec3_config->gain_mask.m1 = config->gain_mask.m1;
	aec3_config->gain_mask.m2 = config->gain_mask.m2;
	aec3_config->gain_mask.m3 = config->gain_mask.m3;
	aec3_config->gain_mask.m5 = config->gain_mask.m5;
	aec3_config->gain_mask.m6 = config->gain_mask.m6;
	aec3_config->gain_mask.m7 = config->gain_mask.m7;
	aec3_config->gain_mask.m8 = config->gain_mask.m8;
	aec3_config->gain_mask.m9 = config->gain_mask.m9;
	aec3_config->gain_mask.gain_curve_offset =
			config->gain_mask.gain_curve_offset;
	aec3_config->gain_mask.gain_curve_slope =
			config->gain_mask.gain_curve_slope;
	aec3_config->gain_mask.temporal_masking_lf =
			config->gain_mask.temporal_masking_lf;
	aec3_config->gain_mask.temporal_masking_hf =
			config->gain_mask.temporal_masking_hf;
	aec3_config->gain_mask.temporal_masking_lf_bands =
			config->gain_mask.temporal_masking_lf_bands;

	aec3_config->echo_audibility = {
		config->echo_audibility.low_render_limit,
		config->echo_audibility.normal_render_limit,
		config->echo_audibility.floor_power,
		config->echo_audibility.audibility_threshold_lf,
		config->echo_audibility.audibility_threshold_mf,
		config->echo_audibility.audibility_threshold_hf,
		static_cast<bool>(
			config->echo_audibility.use_stationary_properties)
	};
	aec3_config->render_levels = {
		config->render_levels.active_render_limit,
		config->render_levels.poor_excitation_render_limit,
	};
	aec3_config->gain_updates.low_noise = {
		config->gain_updates.low_noise.max_inc,
		config->gain_updates.low_noise.max_dec,
		config->gain_updates.low_noise.rate_inc,
		config->gain_updates.low_noise.rate_dec,
		config->gain_updates.low_noise.min_inc,
		config->gain_updates.low_noise.min_dec,
	};
	aec3_config->gain_updates.initial = {
		config->gain_updates.initial.max_inc,
		config->gain_updates.initial.max_dec,
		config->gain_updates.initial.rate_inc,
		config->gain_updates.initial.rate_dec,
		config->gain_updates.initial.min_inc,
		config->gain_updates.initial.min_dec,
	};
	aec3_config->gain_updates.normal = {
		config->gain_updates.normal.max_inc,
		config->gain_updates.normal.max_dec,
		config->gain_updates.normal.rate_inc,
		config->gain_updates.normal.rate_dec,
		config->gain_updates.normal.min_inc,
		config->gain_updates.normal.min_dec,
	};
	aec3_config->gain_updates.saturation = {
		config->gain_updates.saturation.max_inc,
		config->gain_updates.saturation.max_dec,
		config->gain_updates.saturation.rate_inc,
		config->gain_updates.saturation.rate_dec,
		config->gain_updates.saturation.min_inc,
		config->gain_updates.saturation.min_dec,
	};
	aec3_config->gain_updates.nonlinear = {
		config->gain_updates.nonlinear.max_inc,
		config->gain_updates.nonlinear.max_dec,
		config->gain_updates.nonlinear.rate_inc,
		config->gain_updates.nonlinear.rate_dec,
		config->gain_updates.nonlinear.min_inc,
		config->gain_updates.nonlinear.min_dec,
	};
	aec3_config->gain_updates.floor_first_increase =
		config->gain_updates.floor_first_increase;

	aec3_config->echo_removal_control = {
		{
		config->echo_removal_control.gain_rampup.initial_gain,
		config->echo_removal_control.gain_rampup.first_non_zero_gain,
		config->echo_removal_control.gain_rampup.non_zero_gain_blocks,
		config->echo_removal_control.gain_rampup.full_gain_blocks
		},
		static_cast<bool>(config->echo_removal_control.has_clock_drift),
		static_cast<bool>(
			config->echo_removal_control.linear_and_stable_echo_path)
	};

	webrtc::EchoCanceller3Config::EchoModel echo_model;

	echo_model.noise_floor_hold = config->echo_model.noise_floor_hold;
	echo_model.min_noise_floor_power =
			config->echo_model.min_noise_floor_power;
	echo_model.stationary_gate_slope =
			config->echo_model.stationary_gate_slope;
	echo_model.noise_gate_power = config->echo_model.noise_gate_power;
	echo_model.noise_gate_slope = config->echo_model.noise_gate_slope;
	echo_model.render_pre_window_size =
			config->echo_model.render_pre_window_size;
	echo_model.render_post_window_size =
			config->echo_model.render_post_window_size;
	echo_model.nonlinear_hold = config->echo_model.nonlinear_hold;
	echo_model.nonlinear_release = config->echo_model.nonlinear_release;

	aec3_config->echo_model = echo_model;


	return 0;
}

webrtc_apm webrtc_apm_create(unsigned int num_channels,
			     unsigned int frame_rate,
			     struct aec_config *config)
{
	int err;
	webrtc::AudioProcessing *apm;
	webrtc::AudioProcessing::ChannelLayout channel_layout;
	webrtc::AudioProcessingBuilder apm_builder;
	webrtc::EchoCanceller3Config aec3_config;
	std::unique_ptr<webrtc::EchoControlFactory> ec3_factory;

	if (config) {
		convert_to_aec3_config(config, &aec3_config);
		ec3_factory.reset(
			new webrtc::EchoCanceller3Factory(aec3_config));
	} else {
		ec3_factory.reset(new webrtc::EchoCanceller3Factory());
	}

	switch (num_channels) {
		case 1:
			channel_layout = webrtc::AudioProcessing::kMono;
			break;
		case 2:
			channel_layout = webrtc::AudioProcessing::kStereo;
			break;
		default:
			return NULL;
	}

	apm_builder.SetEchoControlFactory(std::move(ec3_factory));
	apm = apm_builder.Create();

	err = apm->Initialize(frame_rate, frame_rate, frame_rate,
			      channel_layout, channel_layout, channel_layout);
	if (err) {
		delete apm;
		return NULL;
	}

	return reinterpret_cast<webrtc_apm>(apm);
}

int webrtc_apm_process_reverse_stream_f(
		webrtc_apm ptr,
		int num_channels, int rate,
		float *const *data)
{
	webrtc::AudioProcessing *apm;
	webrtc::StreamConfig config =
		webrtc::StreamConfig(rate, num_channels);

	apm = reinterpret_cast<webrtc::AudioProcessing *>(ptr);

	return apm->ProcessReverseStream(data, config, config, data);
}

int webrtc_apm_process_reverse_stream(webrtc_apm ptr,
				     int num_channels, int rate,
				     int16_t *data, int nframes)
{
	webrtc::AudioFrame af;
	webrtc::AudioProcessing *apm;

	apm = reinterpret_cast<webrtc::AudioProcessing *>(ptr);

	af.UpdateFrame(0xFFFFFFFF, data, nframes, rate,
		       webrtc::AudioFrame::kNormalSpeech,
		       webrtc::AudioFrame::kVadUnknown,
		       num_channels);
	return apm->ProcessReverseStream(&af);
}

int webrtc_apm_process_stream_f(webrtc_apm ptr,
				int num_channels,
				int rate,
				float *const *data)
{
	webrtc::AudioProcessing *apm;

	webrtc::StreamConfig config =
		webrtc::StreamConfig(rate, num_channels);
	apm = reinterpret_cast<webrtc::AudioProcessing *>(ptr);
	return apm->ProcessStream(data, config, config, data);
}


int webrtc_apm_process_stream(webrtc_apm ptr, int num_channels,
			     int rate, int16_t *data, int nframes)
{
	int ret;
	webrtc::AudioFrame af;
	webrtc::AudioProcessing *apm;

	apm = reinterpret_cast<webrtc::AudioProcessing *>(ptr);
	//set stream delay
	af.UpdateFrame(0xFFFFFFFF, data, nframes, rate,
			webrtc::AudioFrame::kNormalSpeech,
			webrtc::AudioFrame::kVadUnknown,
			num_channels);
	ret = apm->ProcessStream(&af);
	if (ret)
		return ret;

	memcpy(data, af.data(), nframes * num_channels * 2);
	return ret;
}

void webrtc_apm_destroy(webrtc_apm ptr)
{
	webrtc::AudioProcessing *apm;
	apm = reinterpret_cast<webrtc::AudioProcessing *>(ptr);
	delete apm;
}

int webrtc_apm_set_stream_delay(webrtc_apm ptr, int delay_ms)
{
	webrtc::AudioProcessing *apm;

	apm = reinterpret_cast<webrtc::AudioProcessing *>(ptr);
	return apm->set_stream_delay_ms(delay_ms);
}

int webrtc_apm_aec_dump(webrtc_apm ptr, void** wq_ptr, int start, FILE *handle)
{
	webrtc::AudioProcessing *apm;
	rtc::TaskQueue *work_queue;

	apm = reinterpret_cast<webrtc::AudioProcessing *>(ptr);

	if (start) {
		work_queue = new rtc::TaskQueue("aecdump-worker-queue",
						rtc::TaskQueue::Priority::LOW);
		auto aec_dump = webrtc::AecDumpFactory::Create(handle, -1, work_queue);
		if (!aec_dump)
			return -ENOMEM;
		apm->AttachAecDump(std::move(aec_dump));
		*wq_ptr = reinterpret_cast<void *>(work_queue);
	} else {
		apm->DetachAecDump();
		work_queue = reinterpret_cast<rtc::TaskQueue *>(*wq_ptr);
		if (work_queue) {
			delete work_queue;
			work_queue = NULL;
		}
	}
	return 0;
}

int webrtc_apm_has_echo(webrtc_apm ptr)
{
	webrtc::AudioProcessing *apm;

	apm = reinterpret_cast<webrtc::AudioProcessing *>(ptr);
	return apm->echo_cancellation()->stream_has_echo();
}

} // extern "C"
