/*
 *
 *    Copyright (c) 2021 Project CHIP Authors
 *
 *    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 "streamer.h"
#include <lib/shell/Engine.h>
#include <lib/support/CHIPMem.h>
#include <platform/CHIPDeviceLayer.h>

#include <ctype.h>
#include <string.h>

using chip::FormatCHIPError;
using chip::Platform::MemoryAlloc;
using chip::Platform::MemoryFree;
using chip::Shell::Engine;
using chip::Shell::streamer_get;

namespace {

// max > 1
size_t ReadLine(char * buffer, size_t max)
{
    size_t line_sz = 0;

    // Read in characters until we get a line ending or EOT.
    for (bool done = false; !done;)
    {
        // Stop reading if we've run out of space in the buffer (still need to null-terminate).
        if (line_sz >= max - 1u)
        {
            buffer[max - 1] = '\0';
            break;
        }

        if (streamer_read(streamer_get(), buffer + line_sz, 1) != 1)
        {
            continue;
        }

        // Process character we just read.
        switch (buffer[line_sz])
        {
        case '\r':
        case '\n':
            streamer_printf(streamer_get(), "\r\n");
            buffer[line_sz] = '\0';
            line_sz++;
            done = true;
            break;
        case 0x04:
            // Do not accept EOT character (i.e. don't increment line_sz).
            // Stop the read loop if the input is still empty.
            if (line_sz == 0u)
            {
                done = true;
            }
            break;
        case 0x08:
        case 0x7F:
            // Do not accept backspace character (i.e. don't increment line_sz) and remove 1 additional character if it exists.
            if (line_sz >= 1u)
            {
                streamer_printf(streamer_get(), "\b \b");
                line_sz--;
            }
            break;
        default:
            if (isprint(static_cast<int>(buffer[line_sz])) || buffer[line_sz] == '\t')
            {
                streamer_printf(streamer_get(), "%c", buffer[line_sz]);
                line_sz++;
            }
            break;
        }
    }

    // Return the length of the buffer including the terminating null byte.
    return line_sz;
}

bool IsSeparator(char ch)
{
    return (ch == ' ') || (ch == '\t') || (ch == '\r') || (ch == '\n');
}

bool IsEscape(char ch)
{
    return (ch == '\\');
}

bool IsEscapable(char ch)
{
    return IsSeparator(ch) || IsEscape(ch);
}

int TokenizeLine(char * buffer, char ** tokens, int max_tokens)
{
    size_t len = strlen(buffer);
    int cursor = 0;
    size_t i   = 0;

    // Strip leading spaces
    while (buffer[i] && buffer[i] == ' ')
    {
        i++;
    }

    if (len <= i)
    {
        return 0;
    }

    // The first token starts at the beginning.
    tokens[cursor++] = &buffer[i];

    for (; i < len && cursor < max_tokens; i++)
    {
        if (IsEscape(buffer[i]) && IsEscapable(buffer[i + 1]))
        {
            // include the null terminator: strlen(cmd) = strlen(cmd + 1) + 1
            memmove(&buffer[i], &buffer[i + 1], strlen(&buffer[i]));
        }
        else if (IsSeparator(buffer[i]))
        {
            buffer[i] = 0;
            if (!IsSeparator(buffer[i + 1]))
            {
                tokens[cursor++] = &buffer[i + 1];
            }
        }
    }
    // If for too many arguments, overwrite last entry with guard.
    if (cursor >= max_tokens)
    {
        cursor = max_tokens - 1;
    }

    tokens[cursor] = nullptr;

    return cursor;
}

void ProcessShellLine(intptr_t args)
{
    int argc;
    char * argv[CHIP_SHELL_MAX_TOKENS];

    char * line = reinterpret_cast<char *>(args);
    argc        = TokenizeLine(line, argv, CHIP_SHELL_MAX_TOKENS);

    if (argc > 0)
    {
        CHIP_ERROR retval = Engine::Root().ExecCommand(argc, argv);

        if (retval != CHIP_NO_ERROR)
        {
            char errorStr[160];
            bool errorStrFound = FormatCHIPError(errorStr, sizeof(errorStr), retval);
            if (!errorStrFound)
            {
                errorStr[0] = 0;
            }
            streamer_printf(streamer_get(), "Error %s: %s\r\n", argv[0], errorStr);
        }
        else
        {
            streamer_printf(streamer_get(), "Done\r\n", argv[0]);
        }
    }
    MemoryFree(line);
    streamer_printf(streamer_get(), CHIP_SHELL_PROMPT);
}

} // namespace

namespace chip {
namespace Shell {

void Engine::RunMainLoop()
{
    streamer_printf(streamer_get(), CHIP_SHELL_PROMPT);

    while (true)
    {
        char * line = static_cast<char *>(Platform::MemoryAlloc(CHIP_SHELL_MAX_LINE_SIZE));
        if (ReadLine(line, CHIP_SHELL_MAX_LINE_SIZE) == 0u)
        {
            // Stop loop in case of empty read (Ctrl-D).
            break;
        }
#if CONFIG_DEVICE_LAYER
        DeviceLayer::PlatformMgr().ScheduleWork(ProcessShellLine, reinterpret_cast<intptr_t>(line));
#else
        ProcessShellLine(reinterpret_cast<intptr_t>(line));
#endif
    }
}

} // namespace Shell
} // namespace chip
