/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
*
* Copyright 2013 - 2020, nymea GmbH
* Contact: contact@nymea.io
*
* This file is part of nymea.
* This project including source code and documentation is protected by
* copyright law, and remains the property of nymea GmbH. All rights, including
* reproduction, publication, editing and translation, are reserved. The use of
* this project is subject to the terms of a license agreement to be concluded
* with nymea GmbH in accordance with the terms of use of nymea GmbH, available
* under https://nymea.io/license
*
* For any further details and any questions please contact us under
* contact@nymea.io or see our FAQ/Licensing Information on
* https://nymea.io/license/faq
*
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */

#include "integrationpluginsennheiser.h"
#include "plugininfo.h"
#include "ambeosoundbar.h"

#include <network/networkaccessmanager.h>

QHash<QString, QUuid> idMap = {
    {"thingClassId", ambeoThingClassId},
    {"idParamTypeId", ambeoThingIdParamTypeId},

    {"connectedStateTypeId", ambeoConnectedStateTypeId},
    {"playbackStatusStateTypeId", ambeoPlaybackStatusStateTypeId},
    {"playDurationStateTypeId", ambeoPlayDurationStateTypeId},
    {"playTimeStateTypeId", ambeoPlayTimeStateTypeId},
    {"volumeStateTypeId", ambeoVolumeStateTypeId},
    {"muteStateTypeId", ambeoMuteStateTypeId},
    {"titleStateTypeId", ambeoTitleStateTypeId},
    {"artistStateTypeId", ambeoArtistStateTypeId},
    {"collectionStateTypeId", ambeoCollectionStateTypeId},
    {"artworkStateTypeId", ambeoArtworkStateTypeId},
    {"shuffleStateTypeId", ambeoShuffleStateTypeId},
    {"repeatStateTypeId", ambeoRepeatStateTypeId},
    {"powerStateTypeId", ambeoPowerStateTypeId},

    {"playActionTypeId", ambeoPlayActionTypeId},
    {"pauseActionTypeId", ambeoPauseActionTypeId},
    {"stopActionTypeId", ambeoStopActionTypeId},
    {"skipNextActionTypeId", ambeoSkipNextActionTypeId},
    {"skipBackActionTypeId", ambeoSkipBackActionTypeId},
    {"increaseVolumeActionTypeId", ambeoIncreaseVolumeActionTypeId},
    {"decreaseVolumeActionTypeId", ambeoDecreaseVolumeActionTypeId},
};

const QHash<QString, AmbeoSoundBar::AmbeoMode> ambeoModeMap = {
    { "Off", AmbeoSoundBar::AmbeoModeOff },
    { "Light", AmbeoSoundBar::AmbeoModeLight },
    { "Normal", AmbeoSoundBar::AmbeoModeNormal },
    { "Boost", AmbeoSoundBar::AmbeoModeBoost }
};

const QHash<QString, AmbeoSoundBar::EqualizerPreset> ambeoEqualizerPresetMap = {
    { "Neutral", AmbeoSoundBar::EqualizerPresetNeutral },
    { "Movie", AmbeoSoundBar::EqualizerPresetMovie },
    { "Sports", AmbeoSoundBar::EqualizerPresetSports },
    { "News", AmbeoSoundBar::EqualizerPresetNews },
    { "Music", AmbeoSoundBar::EqualizerPresetMusic },
    { "Director", AmbeoSoundBar::EqualizerPresetDirector }
};

IntegrationPluginSennheiser::IntegrationPluginSennheiser(): IntegrationPluginStreamUnlimited(idMap)
{
}

void IntegrationPluginSennheiser::init()
{
    setupZeroConfBrowser("_sennheiser._tcp", "Sennheiser", QString(), "ambeo[\\.]{0,1}soundbar.*");
}

StreamUnlimitedDevice *IntegrationPluginSennheiser::createStreamUnlimitedDevice()
{
    return new AmbeoSoundBar(hardwareManager()->networkManager(), idMap, this);
}

void IntegrationPluginSennheiser::setupThing(ThingSetupInfo *info)
{
    IntegrationPluginStreamUnlimited::setupThing(info);

    Thing *thing = info->thing();
    StreamUnlimitedDevice *device = m_devices.value(thing);

    AmbeoSoundBar *ambeo = dynamic_cast<AmbeoSoundBar*>(device);

    connect(ambeo, &AmbeoSoundBar::nightModeChanged, thing, [thing](bool nightMode){
        thing->setStateValue(ambeoNightModeStateTypeId, nightMode);
    });
    connect(ambeo, &AmbeoSoundBar::equalizerPresetChanged, thing, [thing](AmbeoSoundBar::EqualizerPreset preset){
        thing->setStateValue(ambeoEqualizerPresetStateTypeId, ambeoEqualizerPresetMap.key(preset));
    });
    connect(ambeo, &AmbeoSoundBar::ambeoModeChanged, this, [thing](AmbeoSoundBar::AmbeoMode ambeoMode){
        thing->setStateValue(ambeoAmbeoModeStateTypeId, ambeoModeMap.key(ambeoMode));
    });
    connect(ambeo, &AmbeoSoundBar::inputSourceChanged, this, [thing](const QString &inputSource) {
        thing->setStateValue(ambeoInputSourceStateTypeId, inputSource);
    });
}

void IntegrationPluginSennheiser::executeAction(ThingActionInfo *info)
{
    AmbeoSoundBar *device = dynamic_cast<AmbeoSoundBar*>(m_devices.value(info->thing()));
    QUuid commandId;

    if (info->action().actionTypeId() == ambeoAmbeoModeActionTypeId) {
        commandId = device->setAmbeoMode(ambeoModeMap.value(info->action().param(ambeoAmbeoModeActionAmbeoModeParamTypeId).value().toString()));

    } else if (info->action().actionTypeId() == ambeoNightModeActionTypeId) {
        commandId = device->setNightMode(info->action().param(ambeoNightModeActionNightModeParamTypeId).value().toBool());

    } else if (info->action().actionTypeId() == ambeoEqualizerPresetActionTypeId) {
        commandId = device->setEqualizerPreset(ambeoEqualizerPresetMap.value(info->action().param(ambeoEqualizerPresetActionEqualizerPresetParamTypeId).value().toString()));

    } else if (info->action().actionTypeId() == ambeoInputSourceActionTypeId) {
        commandId = device->setInputSource(info->action().paramValue(ambeoInputSourceActionInputSourceParamTypeId).toString());
    }

    if (!commandId.isNull()) {
        connect(device, &StreamUnlimitedDevice::commandCompleted, info, [=](const QUuid &replyCommandId, bool success){
            if (replyCommandId == commandId) {
                info->finish(success ? Thing::ThingErrorNoError : Thing::ThingErrorHardwareFailure);
            }
        });

    } else {
        IntegrationPluginStreamUnlimited::executeAction(info);
    }
}

