/* Copyright (C) 2016 The Android Open Source Project
**
** This software is licensed under the terms of the GNU General Public
** License version 2, as published by the Free Software Foundation, and
** may be copied, distributed, and modified under those terms.
**
** This program is distributed in the hope that it will be useful,
** but WITHOUT ANY WARRANTY; without even the implied warranty of
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
** GNU General Public License for more details.
*/
#include "TagLengthValue.h"

#include <assert.h>
#include <vector>
#include <stdint.h>
#include <stdio.h>

namespace android {

// The maximum size that can be represented in one size byte, if the size value
// is less than this constant then that's the number of bytes of data. if the
// data is larger than this then the value stored minus this constant will be
// the number of bytes that are used to store the size. So if the value is 0x84
// then 4 bytes are used to store the size. Here are a few examples:
// Size: 0x70,    String: "70"
// Size: 0x80,    String: "80"
// Size: 0x81,    String: "8181"     -- First 81 indicates 1 byte needed (81-80)
// Size: 0x21f3,  String: "8221f3"   -- 82 indicates 2 bytes needed
// Size: 0x12345, String: "83012345" -- 83 indicates 3 bytes needed, zero padded
static const uint32_t kMaxSingleByteSize = 0x80;

void TagLengthValue::populateData(const char* tag,
        std::initializer_list<const TagLengthValue*> data) {
    populateData(tag, data.begin(), data.end());
}

template<class T>
void TagLengthValue::populateData(const char* tag,
        std::initializer_list<const T*> data) {
    populateData(tag, data.begin(), data.end());
}

template<class T>
void TagLengthValue::populateData(const char* tag, T begin, T end) {
    size_t payloadSize = 0;
    for (auto object = begin; object != end; ++object) {
        payloadSize += (*object)->size();
    }
    size_t tagLength = tag ? strlen(tag) : 0;
    // Use half the size because it's not the size in characters but in
    // bytes. Each byte is represented by two characters
    std::string sizeString = createSizeString(payloadSize / 2);
    mData.resize(tagLength + sizeString.size() + payloadSize);
    if (tag && tagLength > 0) {
        memcpy(&mData[0], tag, tagLength);
    }
    memcpy(&mData[tagLength], sizeString.c_str(), sizeString.size());
    size_t offset = tagLength + sizeString.size();

    for (auto object = begin; object != end; ++object) {
        size_t objectSize = (*object)->size();
        memcpy(&mData[offset], (*object)->c_str(), objectSize);
        offset += objectSize;
    }
}

std::string TagLengthValue::createSizeString(size_t size) const {
    char sizeString[16];
    if (size <= kMaxSingleByteSize) {
        snprintf(sizeString, sizeof(sizeString), "%02x",
                 static_cast<uint32_t>(size));
        return sizeString;
    }
    // Sizes larger than 0x80 require size length specifier followed by size
    for (uint32_t numBytes = 1; numBytes <= 4; ++numBytes) {
        if (size < (1ULL << (numBytes * 8))) {
            // The size requires numBytes byte(s) of storage, each byte takes
            // two characters of space in a string in hex representation.
            snprintf(sizeString, sizeof(sizeString), "%02x%0*x",
                     kMaxSingleByteSize + numBytes, 2 * numBytes,
                     static_cast<uint32_t>(size));
            return sizeString;
        }
    }
    assert(false);
    sizeString[0] = '\0';
    return sizeString;
}

const char AidRefDo::kTag[] = "4F";
const char DeviceAppIdRefDo::kTag[] = "C1";
const char RefDo::kTag[] = "E1";
const char ApduArDo::kTag[] = "D0";
const char NfcArDo::kTag[] = "D1";
const char PermArDo::kTag[] = "DB";
const char ArDo::kTag[] = "E3";
const char RefArDo::kTag[] = "E2";
const char AllRefArDo::kTag[] = "FF40";

DeviceAppIdRefDo::DeviceAppIdRefDo(const std::string& stringData) {
    populateData(kTag, { &stringData });
}

RefDo::RefDo(const AidRefDo& aidRefDo,
             const DeviceAppIdRefDo& deviceAppIdRefDo) {
    populateData(kTag, { &aidRefDo, &deviceAppIdRefDo });
}

ApduArDo::ApduArDo(Allow rule) {
    // Allocate enough space for the data plus NULL, then resize down to 2 to
    // avoid modifying the terminating NULL (which is undefined behavior)
    std::string data(3, '0');
    snprintf(&data[0], data.size(), "%02x", static_cast<int>(rule));
    data.resize(2);
    populateData(kTag, { &data });
}

ApduArDo::ApduArDo(std::initializer_list<std::string> rules) {
    std::vector<const std::string*> data;
    for(const auto& rule : rules) {
        data.push_back(&rule);
    }
    populateData(kTag, data.begin(), data.end());
}

NfcArDo::NfcArDo(Allow rule) {
    // Allocate enough space for the data plus NULL, then resize down to 2 to
    // avoid modifying the terminating NULL (which is undefined behavior)
    std::string data(3, '0');
    snprintf(&data[0], data.size(), "%02x", static_cast<int>(rule));
    data.resize(2);
    populateData(kTag, { &data });
}

PermArDo::PermArDo(const std::string& stringData) {
    populateData(kTag, { &stringData });
}

ArDo::ArDo(const ApduArDo& apduArDo) {
    populateData(kTag, { &apduArDo });
}

ArDo::ArDo(const NfcArDo& nfcArDo) {
    populateData(kTag, { &nfcArDo });
}

ArDo::ArDo(const PermArDo& permArDo) {
    populateData(kTag, { &permArDo });
}

ArDo::ArDo(const ApduArDo& apduArDo, const NfcArDo& nfcArDo) {
    populateData(kTag, { &apduArDo, &nfcArDo });
}

RefArDo::RefArDo(const RefDo& refDo, const ArDo& arDo) {
    populateData(kTag, { &refDo, &arDo });
}

AllRefArDo::AllRefArDo(std::initializer_list<RefArDo> refArDos) {
    std::vector<const RefArDo*> data;
    for (const auto& object : refArDos) {
        data.push_back(&object);
    }
    populateData(kTag, data.begin(), data.end());
}

}  // namespace android

