/*
 *
 *    Copyright (c) 2020-2021 Project CHIP Authors
 *    Copyright (c) 2013-2017 Nest Labs, Inc.
 *    All rights reserved.
 *
 *    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 implements an object for writing Abstract Syntax
 *      Notation One (ASN.1) encoded data.
 *
 */

#ifndef __STDC_LIMIT_MACROS
#define __STDC_LIMIT_MACROS
#endif
#include <ctype.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include <lib/asn1/ASN1.h>
#include <lib/core/CHIPCore.h>
#include <lib/core/CHIPEncoding.h>
#include <lib/core/TLV.h>
#include <lib/support/CodeUtils.h>
#include <lib/support/SafeInt.h>

namespace chip {
namespace ASN1 {

using namespace chip::Encoding;

enum
{
    kLengthFieldReserveSize = 1,
    kUnknownLength          = -1,
    kUnknownLengthMarker    = 0xFF
};

void ASN1Writer::Init(uint8_t * buf, size_t maxLen)
{
    mBuf                 = buf;
    mWritePoint          = buf;
    mBufEnd              = buf + maxLen;
    mDeferredLengthCount = 0;
}

void ASN1Writer::InitNullWriter()
{
    mBuf                 = nullptr;
    mWritePoint          = nullptr;
    mBufEnd              = nullptr;
    mDeferredLengthCount = 0;
}

size_t ASN1Writer::GetLengthWritten() const
{
    return (mBuf != nullptr) ? static_cast<size_t>(mWritePoint - mBuf) : 0;
}

CHIP_ERROR ASN1Writer::PutInteger(int64_t val)
{
    uint8_t encodedVal[sizeof(int64_t)];
    uint8_t valStart, valLen;

    BigEndian::Put64(encodedVal, static_cast<uint64_t>(val));

    for (valStart = 0; valStart < 7; valStart++)
    {
        if (encodedVal[valStart] == 0x00 && (encodedVal[valStart + 1] & 0x80) == 0)
            continue;
        if (encodedVal[valStart] == 0xFF && (encodedVal[valStart + 1] & 0x80) == 0x80)
            continue;
        break;
    }
    valLen = static_cast<uint8_t>(8 - valStart);

    return PutValue(kASN1TagClass_Universal, kASN1UniversalTag_Integer, false, encodedVal + valStart, valLen);
}

CHIP_ERROR ASN1Writer::PutBoolean(bool val)
{
    // Do nothing for a null writer.
    VerifyOrReturnError(mBuf != nullptr, CHIP_NO_ERROR);

    ReturnErrorOnFailure(EncodeHead(kASN1TagClass_Universal, kASN1UniversalTag_Boolean, false, 1));

    *mWritePoint++ = (val) ? 0xFF : 0;

    return CHIP_NO_ERROR;
}

CHIP_ERROR ASN1Writer::PutObjectId(const uint8_t * val, uint16_t valLen)
{
    return PutValue(kASN1TagClass_Universal, kASN1UniversalTag_ObjectId, false, val, valLen);
}

CHIP_ERROR ASN1Writer::PutString(uint8_t tag, const char * val, uint16_t valLen)
{
    return PutValue(kASN1TagClass_Universal, tag, false, (const uint8_t *) val, valLen);
}

CHIP_ERROR ASN1Writer::PutOctetString(const uint8_t * val, uint16_t valLen)
{
    return PutValue(kASN1TagClass_Universal, kASN1UniversalTag_OctetString, false, val, valLen);
}

CHIP_ERROR ASN1Writer::PutOctetString(uint8_t cls, uint8_t tag, const uint8_t * val, uint16_t valLen)
{
    return PutValue(cls, tag, false, val, valLen);
}

CHIP_ERROR ASN1Writer::PutOctetString(uint8_t cls, uint8_t tag, chip::TLV::TLVReader & tlvReader)
{
    return PutValue(cls, tag, false, tlvReader);
}

static uint8_t ReverseBits(uint8_t v)
{
    // swap adjacent bits
    v = static_cast<uint8_t>(static_cast<uint8_t>((v >> 1) & 0x55) | static_cast<uint8_t>((v & 0x55) << 1));
    // swap adjacent bit pairs
    v = static_cast<uint8_t>(static_cast<uint8_t>((v >> 2) & 0x33) | static_cast<uint8_t>((v & 0x33) << 2));
    // swap nibbles
    v = static_cast<uint8_t>(static_cast<uint8_t>(v >> 4) | static_cast<uint8_t>(v << 4));
    return v;
}

static uint8_t HighestBit(uint32_t v)
{
    uint32_t highestBit = 0;

    if (v > 0xFFFF)
    {
        highestBit = 16;
        v >>= 16;
    }
    if (v > 0xFF)
    {
        highestBit |= 8;
        v >>= 8;
    }
    if (v > 0xF)
    {
        highestBit |= 4;
        v >>= 4;
    }
    if (v > 0x3)
    {
        highestBit |= 2;
        v >>= 2;
    }
    highestBit |= (v >> 1);

    return static_cast<uint8_t>(highestBit);
}

CHIP_ERROR ASN1Writer::PutBitString(uint32_t val)
{
    uint8_t len;

    // Do nothing for a null writer.
    VerifyOrReturnError(mBuf != nullptr, CHIP_NO_ERROR);

    if (val == 0)
        len = 1;
    else if (val < 256)
        len = 2;
    else if (val < 65536)
        len = 3;
    else if (val < (1 << 24))
        len = 4;
    else
        len = 5;

    ReturnErrorOnFailure(EncodeHead(kASN1TagClass_Universal, kASN1UniversalTag_BitString, false, len));

    if (val == 0)
    {
        mWritePoint[0] = 0;
    }
    else
    {
        mWritePoint[1] = ReverseBits(static_cast<uint8_t>(val));
        if (len >= 3)
        {
            val >>= 8;
            mWritePoint[2] = ReverseBits(static_cast<uint8_t>(val));
            if (len >= 4)
            {
                val >>= 8;
                mWritePoint[3] = ReverseBits(static_cast<uint8_t>(val));
                if (len == 5)
                {
                    val >>= 8;
                    mWritePoint[4] = ReverseBits(static_cast<uint8_t>(val));
                }
            }
        }
        mWritePoint[0] = static_cast<uint8_t>(7 - HighestBit(val));
    }

    mWritePoint += len;

    return CHIP_NO_ERROR;
}

CHIP_ERROR ASN1Writer::PutBitString(uint8_t unusedBitCount, const uint8_t * encodedBits, uint16_t encodedBitsLen)
{
    // Do nothing for a null writer.
    VerifyOrReturnError(mBuf != nullptr, CHIP_NO_ERROR);

    ReturnErrorOnFailure(EncodeHead(kASN1TagClass_Universal, kASN1UniversalTag_BitString, false, encodedBitsLen + 1));

    *mWritePoint++ = unusedBitCount;

    WriteData(encodedBits, encodedBitsLen);

    return CHIP_NO_ERROR;
}

CHIP_ERROR ASN1Writer::PutBitString(uint8_t unusedBitCount, chip::TLV::TLVReader & tlvReader)
{
    ByteSpan encodedBits;

    // Do nothing for a null writer.
    VerifyOrReturnError(mBuf != nullptr, CHIP_NO_ERROR);

    ReturnErrorOnFailure(tlvReader.Get(encodedBits));

    VerifyOrReturnError(CanCastTo<int32_t>(encodedBits.size() + 1), ASN1_ERROR_LENGTH_OVERFLOW);

    ReturnErrorOnFailure(
        EncodeHead(kASN1TagClass_Universal, kASN1UniversalTag_BitString, false, static_cast<int32_t>(encodedBits.size() + 1)));

    *mWritePoint++ = unusedBitCount;

    WriteData(encodedBits.data(), encodedBits.size());

    return CHIP_NO_ERROR;
}

CHIP_ERROR ASN1Writer::PutTime(const ASN1UniversalTime & val)
{
    char buf[ASN1UniversalTime::kASN1TimeStringMaxLength];
    MutableCharSpan bufSpan(buf);
    uint8_t tag;

    ReturnErrorOnFailure(val.ExportTo_ASN1_TIME_string(bufSpan));

    if (val.Year >= 2050)
    {
        tag = kASN1UniversalTag_GeneralizedTime;
    }
    else
    {
        tag = kASN1UniversalTag_UTCTime;
    }
    return PutValue(kASN1TagClass_Universal, tag, false, reinterpret_cast<uint8_t *>(buf), static_cast<uint16_t>(bufSpan.size()));
}

CHIP_ERROR ASN1Writer::PutNull()
{
    return EncodeHead(kASN1TagClass_Universal, kASN1UniversalTag_Null, false, 0);
}

CHIP_ERROR ASN1Writer::PutConstructedType(const uint8_t * val, uint16_t valLen)
{
    // Do nothing for a null writer.
    VerifyOrReturnError(mBuf != nullptr, CHIP_NO_ERROR);

    // Make sure we have enough space to write
    VerifyOrReturnError((mWritePoint + valLen) <= mBufEnd, ASN1_ERROR_OVERFLOW);

    WriteData(val, valLen);

    return CHIP_NO_ERROR;
}

CHIP_ERROR ASN1Writer::StartConstructedType(uint8_t cls, uint8_t tag)
{
    return EncodeHead(cls, tag, true, kUnknownLength);
}

CHIP_ERROR ASN1Writer::EndConstructedType()
{
    return WriteDeferredLength();
}

CHIP_ERROR ASN1Writer::StartEncapsulatedType(uint8_t cls, uint8_t tag, bool bitStringEncoding)
{
    // Do nothing for a null writer.
    VerifyOrReturnError(mBuf != nullptr, CHIP_NO_ERROR);

    ReturnErrorOnFailure(EncodeHead(cls, tag, false, kUnknownLength));

    // If the encapsulating type is BIT STRING, encode the unused bit count field.  Since the BIT
    // STRING contains an ASN.1 DER encoding, and ASN.1 DER encodings are always multiples of 8 bits,
    // the unused bit count is always 0.
    if (bitStringEncoding)
    {
        VerifyOrReturnError(mWritePoint < mBufEnd, ASN1_ERROR_OVERFLOW);
        *mWritePoint++ = 0;
    }

    return CHIP_NO_ERROR;
}

CHIP_ERROR ASN1Writer::EndEncapsulatedType()
{
    return WriteDeferredLength();
}

CHIP_ERROR ASN1Writer::PutValue(uint8_t cls, uint8_t tag, bool isConstructed, const uint8_t * val, uint16_t valLen)
{
    // Do nothing for a null writer.
    VerifyOrReturnError(mBuf != nullptr, CHIP_NO_ERROR);

    ReturnErrorOnFailure(EncodeHead(cls, tag, isConstructed, valLen));

    WriteData(val, valLen);

    return CHIP_NO_ERROR;
}

CHIP_ERROR ASN1Writer::PutValue(uint8_t cls, uint8_t tag, bool isConstructed, chip::TLV::TLVReader & tlvReader)
{
    ByteSpan val;

    // Do nothing for a null writer.
    VerifyOrReturnError(mBuf != nullptr, CHIP_NO_ERROR);

    ReturnErrorOnFailure(tlvReader.Get(val));

    VerifyOrReturnError(CanCastTo<int32_t>(val.size()), ASN1_ERROR_LENGTH_OVERFLOW);

    ReturnErrorOnFailure(EncodeHead(cls, tag, isConstructed, static_cast<int32_t>(val.size())));

    WriteData(val.data(), val.size());

    return CHIP_NO_ERROR;
}

CHIP_ERROR ASN1Writer::EncodeHead(uint8_t cls, uint8_t tag, bool isConstructed, int32_t len)
{
    uint8_t bytesForLen;
    uint32_t totalLen;

    // Do nothing for a null writer.
    VerifyOrReturnError(mBuf != nullptr, CHIP_NO_ERROR);

    // Only tags < 31 supported. The implication of this is that encoded tags are exactly 1 byte long.
    VerifyOrReturnError(tag < 0x1F, ASN1_ERROR_UNSUPPORTED_ENCODING);

    // Only positive and kUnknownLength values are supported for len input.
    VerifyOrReturnError(len >= 0 || len == kUnknownLength, ASN1_ERROR_UNSUPPORTED_ENCODING);

    // Compute the number of bytes required to encode the length.
    bytesForLen = BytesForLength(len);

    // Make sure there's enough space to encode the entire value.
    // Note that the calculated total length doesn't overflow because `len` is a signed value (int32_t).
    // Note that if `len` is not kUnknownLength then it is non-negative (`len` >= 0).
    totalLen = 1 + bytesForLen + static_cast<uint32_t>(len != kUnknownLength ? len : 0);
    VerifyOrReturnError((mWritePoint + totalLen) <= mBufEnd, ASN1_ERROR_OVERFLOW);

    // Write the tag byte.
    *mWritePoint++ = cls | static_cast<uint8_t>(isConstructed ? 0x20 : 0) | tag;

    // Encode the length if it is known.
    if (len != kUnknownLength)
    {
        EncodeLength(mWritePoint, bytesForLen, len);
    }
    // ... otherwise place a marker in the first byte of the length to indicate that the length is unknown
    // and save a pointer to the length field in the deferred-length array.
    //
    // The deferred-length is an array of "pointers" to length fields for which the length of the
    // element was unknown at the time the element head was written. Examples include constructed
    // types such as SEQUENCE and SET, as well non-constructed types that encapsulate other ASN.1 types
    // (e.g. OCTET STRINGS that contain BER/DER encodings). The final lengths are filled in later,
    // at the time the encoding of the element is complete (e.g. when EndConstructed() is called).
    else
    {
        VerifyOrReturnError(mDeferredLengthCount < kMaxDeferredLengthDepth, ASN1_ERROR_INVALID_STATE);

        *mWritePoint                                     = kUnknownLengthMarker;
        mDeferredLengthLocations[mDeferredLengthCount++] = mWritePoint;
    }

    mWritePoint += bytesForLen;

    return CHIP_NO_ERROR;
}

CHIP_ERROR ASN1Writer::WriteDeferredLength()
{
    // Do nothing for a null writer.
    VerifyOrReturnError(mBuf != nullptr, CHIP_NO_ERROR);

    VerifyOrReturnError(mDeferredLengthCount > 0, ASN1_ERROR_INVALID_STATE);

    uint8_t * lenField = mDeferredLengthLocations[mDeferredLengthCount - 1];

    VerifyOrReturnError(*lenField == kUnknownLengthMarker, ASN1_ERROR_INVALID_STATE);

    // Compute the length of the element's value.
    size_t elemLen = static_cast<size_t>((mWritePoint - lenField) - kLengthFieldReserveSize);

    VerifyOrReturnError(CanCastTo<int32_t>(elemLen), ASN1_ERROR_LENGTH_OVERFLOW);

    uint8_t bytesForLen = BytesForLength(static_cast<int32_t>(elemLen));

    // Move the element data if the number of bytes consumed by the final length field
    // is different than the space that was reserved for the field.
    if (bytesForLen != kLengthFieldReserveSize)
    {
        mWritePoint += (bytesForLen - kLengthFieldReserveSize);

        VerifyOrReturnError(mWritePoint <= mBufEnd, ASN1_ERROR_OVERFLOW);

        memmove(lenField + bytesForLen, lenField + kLengthFieldReserveSize, elemLen);
    }

    // Encode the final length of the element, overwriting the unknown length marker
    // in the process.
    EncodeLength(lenField, bytesForLen, static_cast<int32_t>(elemLen));

    mDeferredLengthCount--;

    return CHIP_NO_ERROR;
}

/**
 * Returns the number of bytes required to encode the length value.
 *
 * @param[in]   len     Parameter, which encoding length to be calculated.
 *
 * @return number of bytes required to encode the length value.
 */
uint8_t ASN1Writer::BytesForLength(int32_t len)
{
    if (len == kUnknownLength)
        return kLengthFieldReserveSize;
    if (len < 128)
        return 1;
    if (len < 256)
        return 2;
    if (len < 65536)
        return 3;
    if (len < (1 << 24))
        return 4;
    return 5;
}

void ASN1Writer::EncodeLength(uint8_t * buf, uint8_t bytesForLen, int32_t lenToEncode)
{
    if (bytesForLen == 1)
    {
        buf[0] = static_cast<uint8_t>(lenToEncode);
    }
    else
    {
        --bytesForLen;
        buf[0] = 0x80 | bytesForLen;
        do
        {
            buf[bytesForLen] = static_cast<uint8_t>(lenToEncode);
            lenToEncode >>= 8;
        } while (--bytesForLen);
    }
}

void ASN1Writer::WriteData(const uint8_t * p, size_t len)
{
    memcpy(mWritePoint, p, len);
    mWritePoint += len;
}

} // namespace ASN1
} // namespace chip
