/*
 * Copyright 2016 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */


#include <stdlib.h>
#include <unistd.h>
#include <set>
#include <sstream>

#ifdef __ANDROID__
#include <sys/system_properties.h>
#endif

#include <oboe/AudioStream.h>
#include "oboe/Definitions.h"
#include "oboe/Utilities.h"

namespace oboe {

constexpr float kScaleI16ToFloat = (1.0f / 32768.0f);

void convertFloatToPcm16(const float *source, int16_t *destination, int32_t numSamples) {
    for (int i = 0; i < numSamples; i++) {
        float fval = source[i];
        fval += 1.0; // to avoid discontinuity at 0.0 caused by truncation
        fval *= 32768.0f;
        auto sample = static_cast<int32_t>(fval);
        // clip to 16-bit range
        if (sample < 0) sample = 0;
        else if (sample > 0x0FFFF) sample = 0x0FFFF;
        sample -= 32768; // center at zero
        destination[i] = static_cast<int16_t>(sample);
    }
}

void convertPcm16ToFloat(const int16_t *source, float *destination, int32_t numSamples) {
    for (int i = 0; i < numSamples; i++) {
        destination[i] = source[i] * kScaleI16ToFloat;
    }
}

int32_t convertFormatToSizeInBytes(AudioFormat format) {
    int32_t size = 0;
    switch (format) {
        case AudioFormat::I16:
            size = sizeof(int16_t);
            break;
        case AudioFormat::Float:
            size = sizeof(float);
            break;
        case AudioFormat::I24:
            size = 3; // packed 24-bit data
            break;
        case AudioFormat::I32:
            size = sizeof(int32_t);
            break;
        case AudioFormat::IEC61937:
            size = sizeof(int16_t);
            break;
        case AudioFormat::MP3:
        case AudioFormat::AAC_LC:
        case AudioFormat::AAC_HE_V1:
        case AudioFormat::AAC_HE_V2:
        case AudioFormat::AAC_ELD:
        case AudioFormat::AAC_XHE:
        case AudioFormat::OPUS:
            // For compressed formats, set the size per sample as 0 as they may not have
            // fix size per sample.
            size = 0;
            break;
        default:
            break;
    }
    return size;
}

template<>
const char *convertToText<Result>(Result returnCode) {
    switch (returnCode) {
        case Result::OK:                    return "OK";
        case Result::ErrorDisconnected:     return "ErrorDisconnected";
        case Result::ErrorIllegalArgument:  return "ErrorIllegalArgument";
        case Result::ErrorInternal:         return "ErrorInternal";
        case Result::ErrorInvalidState:     return "ErrorInvalidState";
        case Result::ErrorInvalidHandle:    return "ErrorInvalidHandle";
        case Result::ErrorUnimplemented:    return "ErrorUnimplemented";
        case Result::ErrorUnavailable:      return "ErrorUnavailable";
        case Result::ErrorNoFreeHandles:    return "ErrorNoFreeHandles";
        case Result::ErrorNoMemory:         return "ErrorNoMemory";
        case Result::ErrorNull:             return "ErrorNull";
        case Result::ErrorTimeout:          return "ErrorTimeout";
        case Result::ErrorWouldBlock:       return "ErrorWouldBlock";
        case Result::ErrorInvalidFormat:    return "ErrorInvalidFormat";
        case Result::ErrorOutOfRange:       return "ErrorOutOfRange";
        case Result::ErrorNoService:        return "ErrorNoService";
        case Result::ErrorInvalidRate:      return "ErrorInvalidRate";
        case Result::ErrorClosed:           return "ErrorClosed";
        default:                            return "Unrecognized result";
    }
}

template<>
const char *convertToText<AudioFormat>(AudioFormat format) {
    switch (format) {
        case AudioFormat::Invalid:      return "Invalid";
        case AudioFormat::Unspecified:  return "Unspecified";
        case AudioFormat::I16:          return "I16";
        case AudioFormat::Float:        return "Float";
        case AudioFormat::I24:          return "I24";
        case AudioFormat::I32:          return "I32";
        case AudioFormat::IEC61937:     return "IEC61937";
        case AudioFormat::MP3:          return "MP3";
        case AudioFormat::AAC_LC:       return "AAC_LC";
        case AudioFormat::AAC_HE_V1:    return "AAC_HE_V1";
        case AudioFormat::AAC_HE_V2:    return "AAC_HE_V2";
        case AudioFormat::AAC_ELD:      return "AAC_ELD";
        case AudioFormat::AAC_XHE:      return "AAC_XHE";
        case AudioFormat::OPUS:         return "OPUS";
        default:                        return "Unrecognized format";
    }
}

template<>
const char *convertToText<PerformanceMode>(PerformanceMode mode) {
    switch (mode) {
        case PerformanceMode::LowLatency:   return "LowLatency";
        case PerformanceMode::None:         return "None";
        case PerformanceMode::PowerSaving:  return "PowerSaving";
        default:                            return "Unrecognized performance mode";
    }
}

template<>
const char *convertToText<SharingMode>(SharingMode mode) {
    switch (mode) {
        case SharingMode::Exclusive:    return "Exclusive";
        case SharingMode::Shared:       return "Shared";
        default:                        return "Unrecognized sharing mode";
    }
}

template<>
const char *convertToText<DataCallbackResult>(DataCallbackResult result) {
    switch (result) {
        case DataCallbackResult::Continue:  return "Continue";
        case DataCallbackResult::Stop:      return "Stop";
        default:                            return "Unrecognized data callback result";
    }
}

template<>
const char *convertToText<Direction>(Direction direction) {
    switch (direction) {
        case Direction::Input:  return "Input";
        case Direction::Output: return "Output";
        default:                return "Unrecognized direction";
    }
}

template<>
const char *convertToText<StreamState>(StreamState state) {
    switch (state) {
        case StreamState::Closed:           return "Closed";
        case StreamState::Closing:          return "Closing";
        case StreamState::Disconnected:     return "Disconnected";
        case StreamState::Flushed:          return "Flushed";
        case StreamState::Flushing:         return "Flushing";
        case StreamState::Open:             return "Open";
        case StreamState::Paused:           return "Paused";
        case StreamState::Pausing:          return "Pausing";
        case StreamState::Started:          return "Started";
        case StreamState::Starting:         return "Starting";
        case StreamState::Stopped:          return "Stopped";
        case StreamState::Stopping:         return "Stopping";
        case StreamState::Uninitialized:    return "Uninitialized";
        case StreamState::Unknown:          return "Unknown";
        default:                            return "Unrecognized stream state";
    }
}

template<>
const char *convertToText<AudioApi>(AudioApi audioApi) {

    switch (audioApi) {
        case AudioApi::Unspecified: return "Unspecified";
        case AudioApi::OpenSLES:    return "OpenSLES";
        case AudioApi::AAudio:      return "AAudio";
        default:                    return "Unrecognized audio API";
    }
}

template<>
const char *convertToText<AudioStream*>(AudioStream* stream) {
    static std::string streamText;
    std::stringstream s;

    s<<"StreamID: "<< static_cast<void*>(stream)<<std::endl
     <<"DeviceId: "<<stream->getDeviceId()<<std::endl
     <<"Direction: "<<oboe::convertToText(stream->getDirection())<<std::endl
     <<"API type: "<<oboe::convertToText(stream->getAudioApi())<<std::endl
     <<"BufferCapacity: "<<stream->getBufferCapacityInFrames()<<std::endl
     <<"BufferSize: "<<stream->getBufferSizeInFrames()<<std::endl
     <<"FramesPerBurst: "<< stream->getFramesPerBurst()<<std::endl
     <<"FramesPerDataCallback: "<<stream->getFramesPerDataCallback()<<std::endl
     <<"SampleRate: "<<stream->getSampleRate()<<std::endl
     <<"ChannelCount: "<<stream->getChannelCount()<<std::endl
     <<"Format: "<<oboe::convertToText(stream->getFormat())<<std::endl
     <<"SharingMode: "<<oboe::convertToText(stream->getSharingMode())<<std::endl
     <<"PerformanceMode: "<<oboe::convertToText(stream->getPerformanceMode())
     <<std::endl
     <<"CurrentState: "<<oboe::convertToText(stream->getState())<<std::endl
     <<"XRunCount: "<<stream->getXRunCount()<<std::endl
     <<"FramesRead: "<<stream->getFramesRead()<<std::endl
     <<"FramesWritten: "<<stream->getFramesWritten()<<std::endl;

    streamText = s.str();
    return streamText.c_str();
}

template<>
const char *convertToText<Usage>(Usage usage) {

    switch (usage) {
        case Usage::Media:                         return "Media";
        case Usage::VoiceCommunication:            return "VoiceCommunication";
        case Usage::VoiceCommunicationSignalling:  return "VoiceCommunicationSignalling";
        case Usage::Alarm:                         return "Alarm";
        case Usage::Notification:                  return "Notification";
        case Usage::NotificationRingtone:          return "NotificationRingtone";
        case Usage::NotificationEvent:             return "NotificationEvent";
        case Usage::AssistanceAccessibility:       return "AssistanceAccessibility";
        case Usage::AssistanceNavigationGuidance:  return "AssistanceNavigationGuidance";
        case Usage::AssistanceSonification:        return "AssistanceSonification";
        case Usage::Game:                          return "Game";
        case Usage::Assistant:                     return "Assistant";
        default:                                   return "Unrecognized usage";
    }
}

template<>
const char *convertToText<ContentType>(ContentType contentType) {

    switch (contentType) {
        case ContentType::Speech:        return "Speech";
        case ContentType::Music:         return "Music";
        case ContentType::Movie:         return "Movie";
        case ContentType::Sonification:  return "Sonification";
        default:                         return "Unrecognized content type";
    }
}

template<>
const char *convertToText<InputPreset>(InputPreset inputPreset) {

    switch (inputPreset) {
        case InputPreset::Generic:             return "Generic";
        case InputPreset::Camcorder:           return "Camcorder";
        case InputPreset::VoiceRecognition:    return "VoiceRecognition";
        case InputPreset::VoiceCommunication:  return "VoiceCommunication";
        case InputPreset::Unprocessed:         return "Unprocessed";
        case InputPreset::VoicePerformance:    return "VoicePerformance";
        default:                               return "Unrecognized input preset";
    }
}

template<>
const char *convertToText<SessionId>(SessionId sessionId) {

    switch (sessionId) {
        case SessionId::None:      return "None";
        case SessionId::Allocate:  return "Allocate";
        default:                   return "Unrecognized session id";
    }
}

template<>
const char *convertToText<ChannelCount>(ChannelCount channelCount) {

    switch (channelCount) {
        case ChannelCount::Unspecified:  return "Unspecified";
        case ChannelCount::Mono:         return "Mono";
        case ChannelCount::Stereo:       return "Stereo";
        default:                         return "Unrecognized channel count";
    }
}

template<>
const char *convertToText<SampleRateConversionQuality>(SampleRateConversionQuality sampleRateConversionQuality) {

    switch (sampleRateConversionQuality) {
        case SampleRateConversionQuality::None:     return "None";
        case SampleRateConversionQuality::Fastest:  return "Fastest";
        case SampleRateConversionQuality::Low:      return "Low";
        case SampleRateConversionQuality::Medium:   return "Medium";
        case SampleRateConversionQuality::High:     return "High";
        case SampleRateConversionQuality::Best:     return "Best";
        default:                                    return "Unrecognized sample rate conversion quality";
    }
}

template<>
const char *convertToText<FallbackMode>(FallbackMode fallbackMode) {
    switch (fallbackMode) {
        case FallbackMode::Default: return "Default";
        case FallbackMode::Fail:    return "Fail";
        case FallbackMode::Mute:    return "Mute";
        default:                    return "Unrecognized fallback mode";
    }
}

template<>
const char *convertToText<StretchMode>(StretchMode stretchMode) {
    switch (stretchMode) {
        case StretchMode::Default: return "Default";
        case StretchMode::Voice:   return "Voice";
        default:                   return "Unrecognized stretch mode";
    }
}

std::string getPropertyString(const char * name) {
    std::string result;
#ifdef __ANDROID__
    char valueText[PROP_VALUE_MAX] = {0};
    if (__system_property_get(name, valueText) != 0) {
        result = valueText;
    }
#else
    (void) name;
#endif
    return result;
}

int getPropertyInteger(const char * name, int defaultValue) {
    int result = defaultValue;
#ifdef __ANDROID__
    char valueText[PROP_VALUE_MAX] = {0};
    if (__system_property_get(name, valueText) != 0) {
        result = atoi(valueText);
    }
#else
    (void) name;
#endif
    return result;
}

int getSdkVersion() {
    static int sCachedSdkVersion = -1;
#ifdef __ANDROID__
    if (sCachedSdkVersion == -1) {
        sCachedSdkVersion = getPropertyInteger("ro.build.version.sdk", -1);
    }
#endif
    return sCachedSdkVersion;
}

bool isAtLeastPreReleaseCodename(const std::string& codename) {
    std::string buildCodename = getPropertyString("ro.build.version.codename");
    // Special case "REL", which means the build is not a pre-release build.
    if ("REL" == buildCodename) {
        return false;
    }

    // Otherwise lexically compare them. Return true if the build codename is equal to or
    // greater than the requested codename.
    return buildCodename.compare(codename) >= 0;
}

int getChannelCountFromChannelMask(ChannelMask channelMask) {
    return __builtin_popcount(static_cast<uint32_t>(channelMask));
}


std::set<AudioFormat> COMPRESSED_FORMATS = {
        AudioFormat::MP3, AudioFormat::AAC_LC, AudioFormat::AAC_HE_V1, AudioFormat::AAC_HE_V2,
        AudioFormat::AAC_ELD, AudioFormat::AAC_XHE, AudioFormat::OPUS
};
bool isCompressedFormat(AudioFormat format) {
    return COMPRESSED_FORMATS.count(format) != 0;
}

std::string toString(const PlaybackParameters& parameters) {
    std::stringstream ss;
    ss << "Fallback Mode: " << convertToText(parameters.fallbackMode)
       << ", Stretch Mode:" << convertToText(parameters.stretchMode)
       << ", pitch: " << parameters.pitch
       << ", speed: " << parameters.speed;
    return ss.str();
}

}// namespace oboe
