/*
 *
 *    Copyright (c) 2021 Project CHIP Authors
 *    All rights reserved.
 *
 *    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 <App.h>
#include <AppShellCommands.h>
#include <BindingHandler.h>
#include <LightSwitch.h>
#include <LightingManager.h>
#include <lib/shell/Engine.h>
#include <lib/shell/commands/Help.h>
#include <platform/CHIPDeviceLayer.h>

using namespace chip;
using namespace chip::app;
using namespace chip::Shell;

using Shell::Engine;
using Shell::shell_command_t;
using Shell::streamer_get;
using Shell::streamer_printf;

static Engine AppCmdSubCommands;
static Engine AppCmdLocalSubCommands;
static Engine AppCmdOnOffSubCommands;
static Engine AppCmdGroupsSubCommands;
static Engine AppCmdGroupsOnOffSubCommands;
static Engine AppCmdDebugSubCommands;
static Engine AppCmdIdentifySubCommands;
static Engine AppCmdIdentifyReadSubCommands;

static CHIP_ERROR AppCmdHelpHandler(int argc, char ** argv)
{
    AppCmdSubCommands.ForEachCommand(Shell::PrintCommandHelp, nullptr);
    return CHIP_NO_ERROR;
}

static CHIP_ERROR AppCmdCommandHandler(int argc, char ** argv)
{
    if (argc == 0)
    {
        return AppCmdHelpHandler(argc, argv);
    }

    return AppCmdSubCommands.ExecCommand(argc, argv);
}

namespace Local {

static CHIP_ERROR OnOffHelpHandler(int argc, char ** argv)
{
    AppCmdLocalSubCommands.ForEachCommand(Shell::PrintCommandHelp, nullptr);
    return CHIP_NO_ERROR;
}

static CHIP_ERROR AppCommandHandler(int argc, char ** argv)
{
    if (argc == 0)
    {
        return OnOffHelpHandler(argc, argv);
    }

    return AppCmdLocalSubCommands.ExecCommand(argc, argv);
}

CHIP_ERROR OnCommandHandler(int argc, char ** argv)
{
    streamer_printf(streamer_get(), "Turning the light on ...\n");
    LightMgr().Set(true, PLATFORM_LED_1);

    return CHIP_NO_ERROR;
}

CHIP_ERROR OffCommandHandler(int argc, char ** argv)
{
    streamer_printf(streamer_get(), "Turning the light off ...\n");
    LightMgr().Set(false, PLATFORM_LED_1);

    return CHIP_NO_ERROR;
}

CHIP_ERROR ToggleCommandHandler(int argc, char ** argv)
{
    streamer_printf(streamer_get(), "Toggling the light ...\n");
    if (LightMgr().IsLightOn())
    {
        LightMgr().Set(false, PLATFORM_LED_1);
    }
    else
    {
        LightMgr().Set(true, PLATFORM_LED_1);
    }

    return CHIP_NO_ERROR;
}

} // namespace Local

CHIP_ERROR AssignUnicastData(LightSwitch::Status mStatus)
{
    BindingHandler::BindingData * data = Platform::New<BindingHandler::BindingData>();
    data->EndpointId                   = LightSwitch::GetInstance().GetLightSwitchEndpointId();
    switch (mStatus)
    {
    case LightSwitch::Status::Toggle:
        data->CommandId = Clusters::OnOff::Commands::Toggle::Id;
        break;
    case LightSwitch::Status::On:
        data->CommandId = Clusters::OnOff::Commands::On::Id;
        break;
    case LightSwitch::Status::Off:
        data->CommandId = Clusters::OnOff::Commands::Off::Id;
        break;
    default:
        data->CommandId = Clusters::OnOff::Commands::Off::Id;
        printf("[unicast] default -> Clusters::OnOff::Commands::Off\n");
        break;
    }
    data->ClusterId = Clusters::OnOff::Id;

    DeviceLayer::PlatformMgr().ScheduleWork(BindingHandler::SwitchWorkerHandler, reinterpret_cast<intptr_t>(data));
    return CHIP_NO_ERROR;
}

namespace Unicast {

static CHIP_ERROR OnOffHelpHandler(int argc, char ** argv)
{
    AppCmdOnOffSubCommands.ForEachCommand(Shell::PrintCommandHelp, nullptr);
    return CHIP_NO_ERROR;
}

static CHIP_ERROR AppCommandHandler(int argc, char ** argv)
{
    if (argc == 0)
    {
        return OnOffHelpHandler(argc, argv);
    }

    return AppCmdOnOffSubCommands.ExecCommand(argc, argv);
}

CHIP_ERROR OnCommandHandler(int argc, char ** argv)
{
    return AssignUnicastData(LightSwitch::Status::On);
}

CHIP_ERROR OffCommandHandler(int argc, char ** argv)
{
    return AssignUnicastData(LightSwitch::Status::Off);
}

CHIP_ERROR ToggleCommandHandler(int argc, char ** argv)
{
    return AssignUnicastData(LightSwitch::Status::Toggle);
}

} // namespace Unicast

CHIP_ERROR AssignGroupData(LightSwitch::Status mStatus)
{
    BindingHandler::BindingData * data = Platform::New<BindingHandler::BindingData>();
    data->EndpointId                   = LightSwitch::GetInstance().GetLightSwitchEndpointId();
    switch (mStatus)
    {
    case LightSwitch::Status::Toggle:
        data->CommandId = Clusters::OnOff::Commands::Toggle::Id;
        break;
    case LightSwitch::Status::On:
        data->CommandId = Clusters::OnOff::Commands::On::Id;
        break;
    case LightSwitch::Status::Off:
        data->CommandId = Clusters::OnOff::Commands::Off::Id;
        break;
    default:
        data->CommandId = Clusters::OnOff::Commands::Off::Id;
        printf("[group] default -> Clusters::OnOff::Commands::Off\n");
        break;
    }
    data->ClusterId = Clusters::OnOff::Id;
    data->IsGroup   = true;

    DeviceLayer::PlatformMgr().ScheduleWork(BindingHandler::SwitchWorkerHandler, reinterpret_cast<intptr_t>(data));
    return CHIP_NO_ERROR;
}

namespace Group {

static CHIP_ERROR AppSwitchHelpHandler(int argc, char ** argv)
{
    AppCmdGroupsSubCommands.ForEachCommand(Shell::PrintCommandHelp, nullptr);
    return CHIP_NO_ERROR;
}

static CHIP_ERROR AppCommandHandler(int argc, char ** argv)
{
    if (argc == 0)
    {
        return AppSwitchHelpHandler(argc, argv);
    }

    return AppCmdGroupsSubCommands.ExecCommand(argc, argv);
}

static CHIP_ERROR OnOffHelpHandler(int argc, char ** argv)
{
    AppCmdGroupsOnOffSubCommands.ForEachCommand(Shell::PrintCommandHelp, nullptr);
    return CHIP_NO_ERROR;
}

static CHIP_ERROR OnOffCommandHandler(int argc, char ** argv)
{
    if (argc == 0)
    {
        return OnOffHelpHandler(argc, argv);
    }

    return AppCmdGroupsOnOffSubCommands.ExecCommand(argc, argv);
}

CHIP_ERROR OnCommandHandler(int argc, char ** argv)
{
    return AssignGroupData(LightSwitch::Status::On);
}

CHIP_ERROR OffCommandHandler(int argc, char ** argv)
{
    return AssignGroupData(LightSwitch::Status::Off);
}

CHIP_ERROR ToggleCommandHandler(int argc, char ** argv)
{
    return AssignGroupData(LightSwitch::Status::Toggle);
}

} // namespace Group

namespace Identify {

CHIP_ERROR IdentifyHelpHandler(int argc, char ** argv)
{
    AppCmdIdentifySubCommands.ForEachCommand(Shell::PrintCommandHelp, nullptr);
    return CHIP_NO_ERROR;
}

CHIP_ERROR AppCommandHandler(int argc, char ** argv)
{
    if (argc == 0)
    {
        return IdentifyHelpHandler(argc, argv);
    }

    return AppCmdIdentifySubCommands.ExecCommand(argc, argv);
}

CHIP_ERROR ReadHelpHandler(int argc, char ** argv)
{
    AppCmdIdentifyReadSubCommands.ForEachCommand(Shell::PrintCommandHelp, nullptr);
    return CHIP_NO_ERROR;
}

CHIP_ERROR Read(int argc, char ** argv)
{
    if (argc == 0)
    {
        return ReadHelpHandler(argc, argv);
    }

    return AppCmdIdentifyReadSubCommands.ExecCommand(argc, argv);
}

CHIP_ERROR ReadAttributeList(int argc, char ** argv)
{
    BindingHandler::BindingData * data = Platform::New<BindingHandler::BindingData>();
    data->attributeId                  = Clusters::Identify::Attributes::AttributeList::Id;
    data->ClusterId                    = Clusters::Identify::Id;
    data->isReadAttribute              = true;

    DeviceLayer::PlatformMgr().ScheduleWork(BindingHandler::SwitchWorkerHandler, reinterpret_cast<intptr_t>(data));
    return CHIP_NO_ERROR;
}

CHIP_ERROR ReadFeatureMap(int argc, char ** argv)
{
    BindingHandler::BindingData * data = Platform::New<BindingHandler::BindingData>();
    data->attributeId                  = Clusters::Identify::Attributes::FeatureMap::Id;
    data->ClusterId                    = Clusters::Identify::Id;
    data->isReadAttribute              = true;

    DeviceLayer::PlatformMgr().ScheduleWork(BindingHandler::SwitchWorkerHandler, reinterpret_cast<intptr_t>(data));
    return CHIP_NO_ERROR;
}

} // namespace Identify

namespace Debug {

static CHIP_ERROR DebugHelpHandler(int argc, char ** argv)
{
    AppCmdDebugSubCommands.ForEachCommand(Shell::PrintCommandHelp, nullptr);
    return CHIP_NO_ERROR;
}

static CHIP_ERROR AppCommandHandler(int argc, char ** argv)
{
    if (argc == 0)
    {
        return DebugHelpHandler(argc, argv);
    }

    return AppCmdDebugSubCommands.ExecCommand(argc, argv);
}

CHIP_ERROR StartBLEAdvertisingDebugCommandHandler(int argc, char * argv[])
{
    CHIP_ERROR err = CHIP_NO_ERROR;

    if ((argc > 0) && (strcmp(argv[0], "start") == 0))
    {
        printf("Start BLE advertising ...\n");
        err = StartBLEAdvertisingHandler();
    }
    else if ((argc > 0) && (strcmp(argv[0], "stop") == 0))
    {
        printf("Stop BLE advertising ...\n");
        err = StopBLEAdvertisingHandler();
    }
    else
    {
        return CHIP_ERROR_INVALID_ARGUMENT;
    }

    return err;
}

static CHIP_ERROR TableDebugCommandHandler(int argc, char ** argv)
{
    BindingHandler::GetInstance().PrintBindingTable();
    return CHIP_NO_ERROR;
}

/*
 * Usage: switch debug bind_group [fabric index] [group id] [cluster id]
 */
CHIP_ERROR GroupBindCommandHandler(int argc, char ** argv)
{
    VerifyOrReturnError(argc == 3, CHIP_ERROR_INVALID_ARGUMENT);

    EmberBindingTableEntry * entry = Platform::New<EmberBindingTableEntry>();
    entry->type                    = EMBER_MULTICAST_BINDING;
    entry->local                   = 1; // Hardcoded to endpoint 1 for now
    entry->fabricIndex             = atoi(argv[0]);
    entry->groupId                 = atoi(argv[1]);
    entry->clusterId.SetValue(atoi(argv[3]));

    DeviceLayer::PlatformMgr().ScheduleWork(BindingHandler::BindingWorkerHandler, reinterpret_cast<intptr_t>(entry));
    return CHIP_NO_ERROR;
}

/*
 * Usage: switch debug bind_unicast [fabric index] [node id] [endpoint] [cluster id]
 */
CHIP_ERROR UnicastBindCommandHandler(int argc, char ** argv)
{
    VerifyOrReturnError(argc == 4, CHIP_ERROR_INVALID_ARGUMENT);

    EmberBindingTableEntry * entry = Platform::New<EmberBindingTableEntry>();
    entry->type                    = EMBER_UNICAST_BINDING;
    entry->local                   = 1; // Hardcoded to endpoint 1 for now
    entry->fabricIndex             = atoi(argv[0]);
    entry->nodeId                  = atoi(argv[1]);
    entry->remote                  = atoi(argv[2]);
    entry->clusterId.SetValue(atoi(argv[3]));

    DeviceLayer::PlatformMgr().ScheduleWork(BindingHandler::BindingWorkerHandler, reinterpret_cast<intptr_t>(entry));
    return CHIP_NO_ERROR;
}

/*
 * Usage: switch debug brightness [brightness value]
 */
CHIP_ERROR ChangeBrightnessCommandHandler(int argc, char ** argv)
{
    LightSwitch::GetInstance().DimmerChangeBrightness(atoi(argv[0]));
    return CHIP_NO_ERROR;
}

} // namespace Debug

void RegisterAppShellCommands()
{
    static const shell_command_t ifxAppCmdSubCommands[] = {
        { &AppCmdHelpHandler, "help", "Switch commands" },
        { &Local::AppCommandHandler, "local", "Light-switch on/off local device." },
        { &Unicast::AppCommandHandler, "onoff", "Lightbulb on/off remote device by unicast." },
        { &Group::AppCommandHandler, "groups", "Lightbulb on/off remote device by group." },
        { &Debug::AppCommandHandler, "debug", "Extend the debug command." },
        { &Identify::AppCommandHandler, "identify", "identify read attribute" },
    };

    static const shell_command_t ifxAppCmdLocalSubCommands[] = { { &Local::OnOffHelpHandler, "help",
                                                                   "Usage: switch local [on|off|toggle]" },
                                                                 { &Local::OnCommandHandler, "on", "Make light on" },
                                                                 { &Local::OffCommandHandler, "off", "Make light off" },
                                                                 { &Local::ToggleCommandHandler, "toggle", "Toggle the light" } };

    static const shell_command_t ifxAppCmdOnOffSubCommands[] = {
        { &Unicast::OnOffHelpHandler, "help", "Usage: switch onoff [on|off|toggle]" },
        { &Unicast::OnCommandHandler, "on", "Sends on command to bound Lightbulb" },
        { &Unicast::OffCommandHandler, "off", "Sends off command to bound Lightbulb" },
        { &Unicast::ToggleCommandHandler, "toggle", "Sends toggle command to bound Lightbulb" },
    };

    static const shell_command_t ifxAppCmdGroupsSubCommands[] = {
        { &Group::AppSwitchHelpHandler, "help", "Switch a group of bounded Lightbulbs" },
        { &Group::OnOffCommandHandler, "onoff", "Usage: switch groups onoff [on|off|toggle]" },
    };

    static const shell_command_t ifxAppCmdGroupsOnOffSubCommands[] = {
        { &Group::OnOffHelpHandler, "help", "Usage: switch groups onoff [on|off|toggle]" },
        { &Group::OnCommandHandler, "on", "Sends on command to bound Group" },
        { &Group::OffCommandHandler, "off", "Sends off command to bound Group" },
        { &Group::ToggleCommandHandler, "toggle", "Sends toggle command to bound Group" },
    };

    static const shell_command_t ifxAppCmdDebugSubCommands[] = {
        { &Debug::DebugHelpHandler, "help", "Debug use commands " },
        { &Debug::StartBLEAdvertisingDebugCommandHandler, "bleadv", "Usage: switch debug bleadv [start|stop]" },
        { &Debug::TableDebugCommandHandler, "table", "Print a binding table. Usage: switch debug table" },
        { &Debug::GroupBindCommandHandler, "bind_group", "Usage: switch debug bind_group [fabric index] [group id] [cluster id]" },
        { &Debug::UnicastBindCommandHandler, "bind_unicast",
          "Usage: switch debug bind_unicast [fabric index] [node id] [endpoint] [cluster id]" },
        { &Debug::ChangeBrightnessCommandHandler, "brightness",
          "Change the brightness and range is 0-254. Usage: switch debug brightness [brightness value]" },
    };

    static const shell_command_t ifxAppCmdIdentifySubCommands[] = {
        { &Identify::Read, "read", "Usage: switch identify read <attribute>" },
    };

    static const shell_command_t ifxAppCmdIdentifyReadSubCommands[] = {
        { &Identify::ReadHelpHandler, "help", "Usage: switch identify read <attribute>" },
        { &Identify::ReadAttributeList, "attlist", "attribute list attribute" },
        { &Identify::ReadFeatureMap, "featureMap", "featureMap attribute" },
    };

    static const shell_command_t AppLightSwitchCommand = {
        &AppCmdCommandHandler, "switch", "Light switch commands. Usage: switch [local|onoff|groups|debug][identify]"
    };

    AppCmdSubCommands.RegisterCommands(ifxAppCmdSubCommands, ArraySize(ifxAppCmdSubCommands));
    AppCmdLocalSubCommands.RegisterCommands(ifxAppCmdLocalSubCommands, ArraySize(ifxAppCmdLocalSubCommands));
    AppCmdOnOffSubCommands.RegisterCommands(ifxAppCmdOnOffSubCommands, ArraySize(ifxAppCmdOnOffSubCommands));
    AppCmdGroupsSubCommands.RegisterCommands(ifxAppCmdGroupsSubCommands, ArraySize(ifxAppCmdGroupsSubCommands));
    AppCmdGroupsOnOffSubCommands.RegisterCommands(ifxAppCmdGroupsOnOffSubCommands, ArraySize(ifxAppCmdGroupsOnOffSubCommands));
    AppCmdDebugSubCommands.RegisterCommands(ifxAppCmdDebugSubCommands, ArraySize(ifxAppCmdDebugSubCommands));
    AppCmdIdentifySubCommands.RegisterCommands(ifxAppCmdIdentifySubCommands, ArraySize(ifxAppCmdIdentifySubCommands));
    AppCmdIdentifyReadSubCommands.RegisterCommands(ifxAppCmdIdentifyReadSubCommands, ArraySize(ifxAppCmdIdentifyReadSubCommands));

    Engine::Root().RegisterCommands(&AppLightSwitchCommand, 1);
}
