/*
 * BSD 2-Clause License
 *
 * Copyright (c) 2020, Agnieszka Cicha-Cisek
 * Copyright (c) 2020, Patryk Cisek
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *
 * Redistributions of source code must retain the above copyright notice, this
 * list of conditions and the following disclaimer.
 *
 * Redistributions in binary form must reproduce the above copyright notice,
 * this list of conditions and the following disclaimer in the documentation
 * and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/

#include "totpconverter.h"
#include <stdexcept>


TotpConverter::TotpConverter()
{
}

QString TotpConverter::convertBase32ToHex(const QString &original) const
{
    QString binaryRepresentation = convertBase32ToBinary(original);
    QString hexRepresentation = convertBinaryToHex(binaryRepresentation);
    return hexRepresentation;
}

QString TotpConverter::convertBase32ToBinary(const QString &original) const
{
    // Secrets are really short, so converting to string for code
    // readibility is perfectly fine.
    QString binaryRepresentation;
    for (const auto &ch : original) {
        binaryRepresentation += QString("%1")
                .arg(B32_MAPPING.at(ch.toLatin1()), BIN_NUM_WIDTH, BIN_BASE, QLatin1Char('0'));
    }
    auto len = binaryRepresentation.length();
    binaryRepresentation.resize(len - (len%8));
    return binaryRepresentation;
}

QString TotpConverter::convertBinaryToHex(const QString &original) const
{
    // Similarily to the above, converting to string is never going to be
    // efficiency bottleneck here.
    QString hexRepresentation;
    for (int i = 0; i < original.length(); i = i + BASE32_SEGMENT_LENGHT){
        auto segment = original
                .mid(i, BASE32_SEGMENT_LENGHT);
        hexRepresentation += QString("%1")
                .arg(segment.toInt(nullptr, BIN_BASE),
                     HEX_NUM_WIDTH, HEX_BASE, QLatin1Char('0')).toUpper();
    }
    return hexRepresentation;
}
