/*
 * 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.
*/

#ifndef NITROKEYIMPL_H
#define NITROKEYIMPL_H

#include <memory>
#include <vector>

#include "nitrokeybase.h"
#include "totpslot.h"

namespace nitrokey {
    class NitrokeyManager;
}

/**
 * @brief Actual implementation of NitrokeyBase interface,
 * that uses actual USB key.
 *
 * For detailed documentation see NitrokeyBase.
 */
class NitrokeyImpl : public NitrokeyBase
{
public:
    /**
     * @brief Constructs instance of the class.
     * @param logLevel Log level passed to libnitrokey.
     */
    NitrokeyImpl(int logLevel);
    virtual bool connect() override;
    virtual bool isConnected() const override;
    virtual bool firstAuth(const std::string &adminPin, const std::string &tempPassword) override;
    virtual void userAuth(const std::string &userPin, const std::string &tempPassword) override;
    virtual void writeTotpSlot(std::uint8_t slotNumber, const std::string &slotName,
                               const std::string &hexSecret, std::uint16_t timeWindow,
                               const std::string &temporaryPassword) override;

    virtual void eraseTotpSlot(std::uint8_t slotNumber, const std::string &temporaryPassword) override;

    virtual std::vector<TOTPSlot> getSlots() const override;
    virtual std::string getSlotName(std::uint8_t slot) const override;
    virtual void setTime(std::uint64_t timestamp) const override;
    virtual void setTimeSoft(std::uint64_t timestamp) const override;
    virtual std::string getTOTPCode(const TOTPSlot &slot,
                                    const std::string &tempPassword) const override;

private:
    std::shared_ptr<nitrokey::NitrokeyManager> keyManager;

    TOTPSlot getSlot(std::uint8_t slot) const;
};

#endif // NITROKEYIMPL_H
