/**
 *
 *    Copyright (c) 2020 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.
 */

/**
 *    @file
 *      This file describes a Manul Setup Payload parser based on the
 *      CHIP specification.
 */

#include "ManualSetupPayloadParser.h"

#include <support/logging/CHIPLogging.h>
#include <support/verhoeff/Verhoeff.h>

#include <iostream>
#include <math.h>
#include <string>
#include <vector>

using namespace chip;
using namespace std;

static CHIP_ERROR checkDecimalStringValidity(string decimalString, string & decimalStringWithoutCheckDigit)
{
    if (decimalString.length() < 2)
    {
        ChipLogError(SetupPayload, "Failed decoding base10. Input was empty. %zu", decimalString.length());
        return CHIP_ERROR_INVALID_STRING_LENGTH;
    }
    string repWithoutCheckChar = decimalString.substr(0, decimalString.length() - 1);
    char checkChar             = decimalString.back();

    if (!Verhoeff10::ValidateCheckChar(checkChar, repWithoutCheckChar.c_str()))
    {
        return CHIP_ERROR_INTEGRITY_CHECK_FAILED;
    }
    decimalStringWithoutCheckDigit = repWithoutCheckChar;
    return CHIP_NO_ERROR;
}

static CHIP_ERROR checkCodeLengthValidity(string decimalString, bool isLongCode)
{
    size_t expectedCharLength = isLongCode ? kManualSetupLongCodeCharLength : kManualSetupShortCodeCharLength;
    if (decimalString.length() != expectedCharLength)
    {
        ChipLogError(SetupPayload, "Failed decoding base10. Input length %zu was not expected length %zu", decimalString.length(),
                     expectedCharLength);
        return CHIP_ERROR_INVALID_STRING_LENGTH;
    }
    return CHIP_NO_ERROR;
}

// Extract n bits starting at index i and store it in dest
static CHIP_ERROR extractBits(uint32_t number, uint64_t & dest, int index, int numberBits, int maxBits)
{
    if ((index + numberBits) > maxBits)
    {
        ChipLogError(SetupPayload, "Number %u maxBits %d index %d n %d", number, maxBits, index, numberBits);
        return CHIP_ERROR_INVALID_STRING_LENGTH;
    }
    dest = (((1 << numberBits) - 1) & (number >> index));
    return CHIP_NO_ERROR;
}

static CHIP_ERROR toNumber(string decimalString, uint64_t & dest)
{
    uint64_t number = 0;
    for (uint i = 0; i < decimalString.length(); i++)
    {
        if (!isdigit(decimalString[i]))
        {
            ChipLogError(SetupPayload, "Failed decoding base10. Character was invalid %c", decimalString[i]);
            return CHIP_ERROR_INVALID_INTEGER_VALUE;
        }
        number *= 10;
        number += decimalString[i] - '0';
    }
    dest = number;
    return CHIP_NO_ERROR;
}

// Populate numberOfChars into dest from decimalString starting at startIndex (least significant digit = left-most digit)
static CHIP_ERROR readDigitsFromDecimalString(string decimalString, int & index, uint64_t & dest, size_t numberOfCharsToRead)
{
    if (decimalString.length() < numberOfCharsToRead || (numberOfCharsToRead + index > decimalString.length()))
    {
        ChipLogError(SetupPayload, "Failed decoding base10. Input was too short. %zu", decimalString.length());
        return CHIP_ERROR_INVALID_STRING_LENGTH;
    }
    else if (index < 0)
    {
        ChipLogError(SetupPayload, "Failed decoding base10. Index was negative. %d", index);
        return CHIP_ERROR_INVALID_ARGUMENT;
    }

    string decimalSubstring = decimalString.substr(index, numberOfCharsToRead);
    index += numberOfCharsToRead;
    return toNumber(decimalSubstring, dest);
}

// Populate numberOfBits into dest from number starting at startIndex (LSB = right-most bit)
static CHIP_ERROR readBitsFromNumber(int32_t number, int & index, uint64_t & dest, size_t numberOfBitsToRead, size_t maxBits)
{
    uint64_t bits     = 0;
    CHIP_ERROR result = extractBits(number, bits, index, numberOfBitsToRead, maxBits);
    if (result != CHIP_NO_ERROR)
    {
        return result;
    }

    index += numberOfBitsToRead;
    dest = bits;
    return CHIP_NO_ERROR;
}

CHIP_ERROR ManualSetupPayloadParser::populatePayload(SetupPayload & outPayload)
{
    CHIP_ERROR result = CHIP_NO_ERROR;
    SetupPayload payload;
    string representationWithoutCheckDigit;

    result = checkDecimalStringValidity(mDecimalStringRepresentation, representationWithoutCheckDigit);
    if (result != CHIP_NO_ERROR)
    {
        return result;
    }

    int stringOffset = 0;
    uint64_t shortCode;
    result = readDigitsFromDecimalString(representationWithoutCheckDigit, stringOffset, shortCode, kManualSetupShortCodeCharLength);
    if (result != CHIP_NO_ERROR)
    {
        return result;
    }

    bool isLongCode = (shortCode & 1) == 1;
    result          = checkCodeLengthValidity(representationWithoutCheckDigit, isLongCode);
    if (result != CHIP_NO_ERROR)
    {
        return result;
    }

    int numberOffset = 1;
    uint64_t setUpPINCode;
    size_t maxShortCodeBitsLength = 1 + kSetupPINCodeFieldLengthInBits + kManualSetupDiscriminatorFieldLengthInBits;

    uint64_t discriminator;
    result = readBitsFromNumber(shortCode, numberOffset, discriminator, kManualSetupDiscriminatorFieldLengthInBits,
                                maxShortCodeBitsLength);
    if (result != CHIP_NO_ERROR)
    {
        return result;
    }

    result = readBitsFromNumber(shortCode, numberOffset, setUpPINCode, kSetupPINCodeFieldLengthInBits, maxShortCodeBitsLength);
    if (result != CHIP_NO_ERROR)
    {
        return result;
    }
    else if (setUpPINCode == 0)
    {
        ChipLogError(SetupPayload, "Failed decoding base10. SetUpPINCode was 0.");
        return CHIP_ERROR_INVALID_ARGUMENT;
    }

    if (isLongCode)
    {
        uint64_t vendorID;
        result =
            readDigitsFromDecimalString(representationWithoutCheckDigit, stringOffset, vendorID, kManualSetupVendorIdCharLength);
        if (result != CHIP_NO_ERROR)
        {
            return result;
        }

        uint64_t productID;
        result =
            readDigitsFromDecimalString(representationWithoutCheckDigit, stringOffset, productID, kManualSetupProductIdCharLength);
        if (result != CHIP_NO_ERROR)
        {
            return result;
        }
        outPayload.vendorID  = vendorID;
        outPayload.productID = productID;
    }
    outPayload.setUpPINCode  = setUpPINCode;
    outPayload.discriminator = discriminator;

    return result;
}
