/*
 *
 *    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 "MatterShell.h"
#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 {

constexpr char kShellPrompt[] = "matterCli> ";

// To track carriage returns of Windows return cases of '\r\n'
bool haveCR = false;

void ReadLine(char * buffer, size_t max)
{
    size_t line_sz = 0;
    size_t read    = 0;
    bool done      = false;

    // Read in characters until we get a line ending or EOT.
    while ((line_sz < max) && !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;
        }

        chip::WaitForShellActivity();
        while (streamer_read(streamer_get(), buffer + read, 1) == 1)
        {
            // Count how many characters were read; usually one but could be copy/paste
            read++;
        }
        // Process all characters that were read until we run out or exceed max char limit
        while (line_sz < read && line_sz < max)
        {
            switch (buffer[line_sz])
            {
            case '\r':
                // Mac OS return case of '\r' or beginning of Windows return case '\r\n'
                buffer[line_sz] = '\0';
                streamer_printf(streamer_get(), "\r\n");
                haveCR = true;
                done   = true;
                line_sz++;
                break;
            case '\n':
                // True if Windows return case of '\r\n'
                if (haveCR)
                {
                    // Do nothing - already taken care of with CR, return to loop and don't increment buffer
                    haveCR = false;
                    read--;
                }
                // Linux return case of just '\n'
                else
                {
                    buffer[line_sz] = '\0';
                    streamer_printf(streamer_get(), "\r\n");
                    done = true;
                    line_sz++;
                }
                break;
            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)
                {
                    // Delete backspace character + whatever came before it
                    streamer_printf(streamer_get(), "\b \b");
                    line_sz--;
                    read--;
                }
                // Remove backspace character regardless
                read--;

                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;
            }
        }
    }
}

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;
            // Don't treat the previous character as a separator if this one is 0
            // otherwise the trailing space will become a token
            if (!IsSeparator(buffer[i + 1]) && buffer[i + 1] != 0)
            {
                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(), kShellPrompt);
}

} // namespace

namespace chip {
namespace Shell {

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

    while (true)
    {
        char * line = static_cast<char *>(Platform::MemoryAlloc(CHIP_SHELL_MAX_LINE_SIZE));
        ReadLine(line, CHIP_SHELL_MAX_LINE_SIZE);
#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
