/*
 *  Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.
 *
 *  Use of this source code is governed by a BSD-style license
 *  that can be found in the LICENSE file in the root of the source
 *  tree. An additional intellectual property rights grant can be found
 *  in the file PATENTS.  All contributing project authors may
 *  be found in the AUTHORS file in the root of the source tree.
 */

#include "voe_call_report_impl.h"

#include "audio_processing.h"
#include "channel.h"
#include "critical_section_wrapper.h"
#include "file_wrapper.h"
#include "trace.h"
#include "voe_errors.h"
#include "voice_engine_impl.h"

namespace webrtc
{

VoECallReport* VoECallReport::GetInterface(VoiceEngine* voiceEngine)
{
#ifndef WEBRTC_VOICE_ENGINE_CALL_REPORT_API
    return NULL;
#else
    if (NULL == voiceEngine)
    {
        return NULL;
    }
    VoiceEngineImpl* s =
            reinterpret_cast<VoiceEngineImpl*> (voiceEngine);
    VoECallReportImpl* d = s;
    (*d)++;
    return (d);
#endif
}

#ifdef WEBRTC_VOICE_ENGINE_CALL_REPORT_API

VoECallReportImpl::VoECallReportImpl() :
    _file(*FileWrapper::Create())
{
    WEBRTC_TRACE(kTraceMemory, kTraceVoice, VoEId(_instanceId, -1),
                 "VoECallReportImpl() - ctor");
}

VoECallReportImpl::~VoECallReportImpl()
{
    WEBRTC_TRACE(kTraceMemory, kTraceVoice, VoEId(_instanceId, -1),
                 "~VoECallReportImpl() - dtor");
    delete &_file;
}

int VoECallReportImpl::Release()
{
    WEBRTC_TRACE(kTraceApiCall, kTraceVoice, VoEId(_instanceId, -1),
                 "VoECallReportImpl::Release()");
    (*this)--;
    int refCount = GetCount();
    if (refCount < 0)
    {
        Reset();
        _engineStatistics.SetLastError(VE_INTERFACE_NOT_FOUND,
                                       kTraceWarning);
        return (-1);
    }
    WEBRTC_TRACE(kTraceStateInfo, kTraceVoice, VoEId(_instanceId, -1),
                 "VoECallReportImpl reference counter = %d", refCount);
    return (refCount);
}

int VoECallReportImpl::ResetCallReportStatistics(int channel)
{
    WEBRTC_TRACE(kTraceApiCall, kTraceVoice, VoEId(_instanceId, -1),
                 "ResetCallReportStatistics(channel=%d)", channel);
    ANDROID_NOT_SUPPORTED(_engineStatistics);
    IPHONE_NOT_SUPPORTED();

    if (!_engineStatistics.Initialized())
    {
        _engineStatistics.SetLastError(VE_NOT_INITED, kTraceError);
        return -1;
    }
    assert(_audioProcessingModulePtr != NULL);

    bool echoMode =
        _audioProcessingModulePtr->echo_cancellation()->are_metrics_enabled();

    WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId, -1),
                 "  current AudioProcessingModule echo metric state %d)",
                 echoMode);
    // Reset the APM statistics
    if (_audioProcessingModulePtr->echo_cancellation()->enable_metrics(true)
        != 0)
    {
        _engineStatistics.SetLastError(VE_APM_ERROR, kTraceError,
                                       "ResetCallReportStatistics() unable to "
                                       "set the AudioProcessingModule echo "
                                       "metrics state");
        return -1;
    }
    // Restore metric states
    _audioProcessingModulePtr->echo_cancellation()->enable_metrics(echoMode);

    // Reset channel dependent statistics
    if (channel != -1)
    {
        voe::ScopedChannel sc(_channelManager, channel);
        voe::Channel* channelPtr = sc.ChannelPtr();
        if (channelPtr == NULL)
        {
            _engineStatistics.SetLastError(VE_CHANNEL_NOT_VALID, kTraceError,
                                           "ResetCallReportStatistics() failed "
                                           "to locate channel");
            return -1;
        }
        channelPtr->ResetDeadOrAliveCounters();
        channelPtr->ResetRTCPStatistics();
    }
    else
    {
        WebRtc_Word32 numOfChannels = _channelManager.NumOfChannels();
        if (numOfChannels <= 0)
        {
            return 0;
        }
        WebRtc_Word32* channelsArray = new WebRtc_Word32[numOfChannels];
        _channelManager.GetChannelIds(channelsArray, numOfChannels);
        for (int i = 0; i < numOfChannels; i++)
        {
            voe::ScopedChannel sc(_channelManager, channelsArray[i]);
            voe::Channel* channelPtr = sc.ChannelPtr();
            if (channelPtr)
            {
                channelPtr->ResetDeadOrAliveCounters();
                channelPtr->ResetRTCPStatistics();
            }
        }
        delete[] channelsArray;
    }

    return 0;
}

int VoECallReportImpl::GetEchoMetricSummary(EchoStatistics& stats)
{
    WEBRTC_TRACE(kTraceApiCall, kTraceVoice, VoEId(_instanceId, -1),
                 "GetEchoMetricSummary()");
    ANDROID_NOT_SUPPORTED(_engineStatistics);
    IPHONE_NOT_SUPPORTED();

    if (!_engineStatistics.Initialized())
    {
        _engineStatistics.SetLastError(VE_NOT_INITED, kTraceError);
        return -1;
    }
    assert(_audioProcessingModulePtr != NULL);

    return (GetEchoMetricSummaryInternal(stats));
}

int VoECallReportImpl::GetEchoMetricSummaryInternal(EchoStatistics& stats)
{
    // Retrieve echo metrics from the AudioProcessingModule
    int ret(0);
    bool mode(false);
    EchoCancellation::Metrics metrics;

    // Ensure that echo metrics is enabled

    mode =
        _audioProcessingModulePtr->echo_cancellation()->are_metrics_enabled();
    if (mode != false)
    {
        ret =
          _audioProcessingModulePtr->echo_cancellation()->GetMetrics(&metrics);
        if (ret != 0)
        {
            WEBRTC_TRACE(kTraceWarning, kTraceVoice, VoEId(_instanceId, -1),
                       "  AudioProcessingModule GetMetrics() => error");
        }
    }
    else
    {
        WEBRTC_TRACE(kTraceWarning, kTraceVoice, VoEId(_instanceId, -1),
                   "  AudioProcessingModule echo metrics is not enabled");
    }

    if ((ret != 0) || (mode == false))
    {
        // Mark complete struct as invalid (-100 dB)
        WEBRTC_TRACE(kTraceWarning, kTraceVoice, VoEId(_instanceId, -1),
                   "  unable to retrieve echo metrics from the "
                   "AudioProcessingModule");
        stats.erl.min = -100;
        stats.erl.max = -100;
        stats.erl.average = -100;
        stats.erle.min = -100;
        stats.erle.max = -100;
        stats.erle.average = -100;
        stats.rerl.min = -100;
        stats.rerl.max = -100;
        stats.rerl.average = -100;
        stats.a_nlp.min = -100;
        stats.a_nlp.max = -100;
        stats.a_nlp.average = -100;
    }
    else
    {

        // Deliver output results to user
        stats.erl.min = metrics.echo_return_loss.minimum;
        stats.erl.max = metrics.echo_return_loss.maximum;
        stats.erl.average = metrics.echo_return_loss.average;
        WEBRTC_TRACE(kTraceStateInfo, kTraceVoice, VoEId(_instanceId, -1),
                   "  erl: min=%d, max=%d, avg=%d", stats.erl.min,
                   stats.erl.max, stats.erl.average);

        stats.erle.min = metrics.echo_return_loss_enhancement.minimum;
        stats.erle.max = metrics.echo_return_loss_enhancement.maximum;
        stats.erle.average = metrics.echo_return_loss_enhancement.average;
        WEBRTC_TRACE(kTraceStateInfo, kTraceVoice, VoEId(_instanceId, -1),
                   "  erle: min=%d, max=%d, avg=%d", stats.erle.min,
                   stats.erle.max, stats.erle.average);

        stats.rerl.min = metrics.residual_echo_return_loss.minimum;
        stats.rerl.max = metrics.residual_echo_return_loss.maximum;
        stats.rerl.average = metrics.residual_echo_return_loss.average;
        WEBRTC_TRACE(kTraceStateInfo, kTraceVoice, VoEId(_instanceId, -1),
                   "  rerl: min=%d, max=%d, avg=%d", stats.rerl.min,
                   stats.rerl.max, stats.rerl.average);

        stats.a_nlp.min = metrics.a_nlp.minimum;
        stats.a_nlp.max = metrics.a_nlp.maximum;
        stats.a_nlp.average = metrics.a_nlp.average;
        WEBRTC_TRACE(kTraceStateInfo, kTraceVoice, VoEId(_instanceId, -1),
                   "  a_nlp: min=%d, max=%d, avg=%d", stats.a_nlp.min,
                   stats.a_nlp.max, stats.a_nlp.average);
    }
    return 0;
}

int VoECallReportImpl::GetRoundTripTimeSummary(int channel, StatVal& delaysMs)
{
    WEBRTC_TRACE(kTraceApiCall, kTraceVoice, VoEId(_instanceId, -1),
                 "GetRoundTripTimeSummary()");
    ANDROID_NOT_SUPPORTED(_engineStatistics);
    IPHONE_NOT_SUPPORTED();

    if (!_engineStatistics.Initialized())
    {
        _engineStatistics.SetLastError(VE_NOT_INITED, kTraceError);
        return -1;
    }
    voe::ScopedChannel sc(_channelManager, channel);
    voe::Channel* channelPtr = sc.ChannelPtr();
    if (channelPtr == NULL)
    {
        _engineStatistics.SetLastError(VE_CHANNEL_NOT_VALID, kTraceError,
                                       "GetRoundTripTimeSummary() failed to "
                                       "locate channel");
        return -1;
    }

    return channelPtr->GetRoundTripTimeSummary(delaysMs);
}

int VoECallReportImpl::GetDeadOrAliveSummary(int channel,
                                             int& numOfDeadDetections,
                                             int& numOfAliveDetections)
{
    WEBRTC_TRACE(kTraceApiCall, kTraceVoice, VoEId(_instanceId, -1),
                 "GetDeadOrAliveSummary(channel=%d)", channel);
    ANDROID_NOT_SUPPORTED(_engineStatistics);
    IPHONE_NOT_SUPPORTED();

    if (!_engineStatistics.Initialized())
    {
        _engineStatistics.SetLastError(VE_NOT_INITED, kTraceError);
        return -1;
    }

    return (GetDeadOrAliveSummaryInternal(channel, numOfDeadDetections,
                                          numOfAliveDetections));
}

int VoECallReportImpl::GetDeadOrAliveSummaryInternal(int channel,
                                                     int& numOfDeadDetections,
                                                     int& numOfAliveDetections)
{
    WEBRTC_TRACE(kTraceApiCall, kTraceVoice, VoEId(_instanceId, -1),
                 "GetDeadOrAliveSummary(channel=%d)", channel);

    if (!_engineStatistics.Initialized())
    {
        _engineStatistics.SetLastError(VE_NOT_INITED, kTraceError);
        return -1;
    }
    voe::ScopedChannel sc(_channelManager, channel);
    voe::Channel* channelPtr = sc.ChannelPtr();
    if (channelPtr == NULL)
    {
        _engineStatistics.SetLastError(VE_CHANNEL_NOT_VALID, kTraceError,
                                       "GetRoundTripTimeSummary() failed to "
                                       "locate channel");
        return -1;
    }

    return channelPtr->GetDeadOrAliveCounters(numOfDeadDetections,
                                              numOfAliveDetections);
}

int VoECallReportImpl::WriteReportToFile(const char* fileNameUTF8)
{
    WEBRTC_TRACE(kTraceApiCall, kTraceVoice, VoEId(_instanceId, -1),
                 "WriteReportToFile(fileNameUTF8=%s)", fileNameUTF8);
    ANDROID_NOT_SUPPORTED(_engineStatistics);
    IPHONE_NOT_SUPPORTED();

    if (!_engineStatistics.Initialized())
    {
        _engineStatistics.SetLastError(VE_NOT_INITED, kTraceError);
        return -1;
    }

    if (NULL == fileNameUTF8)
    {
        _engineStatistics.SetLastError(VE_INVALID_ARGUMENT, kTraceError,
                                       "WriteReportToFile() invalid filename");
        return -1;
    }

    if (_file.Open())
    {
        _file.CloseFile();
    }

    // Open text file in write mode
    if (_file.OpenFile(fileNameUTF8, false, false, true) != 0)
    {
        _engineStatistics.SetLastError(VE_BAD_FILE, kTraceError,
                                       "WriteReportToFile() unable to open the "
                                       "file");
        return -1;
    }

    // Summarize information and add it to the open file
    //
    _file.WriteText("WebRtc VoiceEngine Call Report\n");
    _file.WriteText("==============================\n");
    _file.WriteText("\nNetwork Packet Round Trip Time (RTT)\n");
    _file.WriteText("------------------------------------\n\n");

    WebRtc_Word32 numOfChannels = _channelManager.NumOfChannels();
    if (numOfChannels <= 0)
    {
        return 0;
    }
    WebRtc_Word32* channelsArray = new WebRtc_Word32[numOfChannels];
    _channelManager.GetChannelIds(channelsArray, numOfChannels);
    for (int ch = 0; ch < numOfChannels; ch++)
    {
        voe::ScopedChannel sc(_channelManager, channelsArray[ch]);
        voe::Channel* channelPtr = sc.ChannelPtr();
        if (channelPtr)
        {
            StatVal delaysMs;
            _file.WriteText("channel %d:\n", ch);
            channelPtr->GetRoundTripTimeSummary(delaysMs);
            _file.WriteText("  min:%5d [ms]\n", delaysMs.min);
            _file.WriteText("  max:%5d [ms]\n", delaysMs.max);
            _file.WriteText("  avg:%5d [ms]\n", delaysMs.average);
        }
    }

    _file.WriteText("\nDead-or-Alive Connection Detections\n");
    _file.WriteText("------------------------------------\n\n");

    for (int ch = 0; ch < numOfChannels; ch++)
    {
        voe::ScopedChannel sc(_channelManager, channelsArray[ch]);
        voe::Channel* channelPtr = sc.ChannelPtr();
        if (channelPtr)
        {
            int nDead(0);
            int nAlive(0);
            _file.WriteText("channel %d:\n", ch);
            GetDeadOrAliveSummary(ch, nDead, nAlive);
            _file.WriteText("  #dead :%6d\n", nDead);
            _file.WriteText("  #alive:%6d\n", nAlive);
        }
    }

    delete[] channelsArray;

    EchoStatistics echo;
    GetEchoMetricSummary(echo);

    _file.WriteText("\nEcho Metrics\n");
    _file.WriteText("------------\n\n");

    _file.WriteText("erl:\n");
    _file.WriteText("  min:%5d [dB]\n", echo.erl.min);
    _file.WriteText("  max:%5d [dB]\n", echo.erl.max);
    _file.WriteText("  avg:%5d [dB]\n", echo.erl.average);
    _file.WriteText("\nerle:\n");
    _file.WriteText("  min:%5d [dB]\n", echo.erle.min);
    _file.WriteText("  max:%5d [dB]\n", echo.erle.max);
    _file.WriteText("  avg:%5d [dB]\n", echo.erle.average);
    _file.WriteText("rerl:\n");
    _file.WriteText("  min:%5d [dB]\n", echo.rerl.min);
    _file.WriteText("  max:%5d [dB]\n", echo.rerl.max);
    _file.WriteText("  avg:%5d [dB]\n", echo.rerl.average);
    _file.WriteText("a_nlp:\n");
    _file.WriteText("  min:%5d [dB]\n", echo.a_nlp.min);
    _file.WriteText("  max:%5d [dB]\n", echo.a_nlp.max);
    _file.WriteText("  avg:%5d [dB]\n", echo.a_nlp.average);

    _file.WriteText("\n<END>");

    _file.Flush();
    _file.CloseFile();

    return 0;
}

#endif  // WEBRTC_VOICE_ENGINE_CALL_REPORT_API

} // namespace webrtc
