/*
 *
 *    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
        // NotifyShellProcess() 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
