/*
 *
 *    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 "matter_shell.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;
        }

#ifdef BRD4325A
        // for 917 SoC board, we need to create a rx event before we wait for the shell activity
        // NotifyShellProcessFromISR() is called once the buffer is filled
        while (streamer_read(streamer_get(), buffer + read, 1) == 1)
        {
            // Count how many characters were read; usually one but could be copy/paste
            read++;
        }
#endif
        chip::WaitForShellActivity();
#ifndef BRD4325A
        // for EFR32 boards
        while (streamer_read(streamer_get(), buffer + read, 1) == 1)
        {
            // Count how many characters were read; usually one but could be copy/paste
            read++;
        }
#endif
        // 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);
#ifdef BRD4325A
    // small delay for uart print
    vTaskDelay(1);
#endif
    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
