// Copyright 2021 Google LLC
//
// 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.

#pragma once
#include <flasher/device.hpp>
#include <flasher/device/fake.hpp>
#include <flasher/file/memory.hpp>
#include <flasher/mutate.hpp>

#include <cstddef>
#include <utility>

#include <gmock/gmock.h>
#include <gtest/gtest.h>

namespace flasher
{
namespace ops
{

inline constexpr std::byte operator""_b(unsigned long long t)
{
    return static_cast<std::byte>(t);
}

class MockOrFakeDevice : public device::Fake
{
  public:
    MOCK_METHOD(std::span<std::byte>, readAt,
                (std::span<std::byte> buf, size_t offset), (override));
    MOCK_METHOD(std::span<const std::byte>, writeAt,
                (std::span<const std::byte> data, size_t offset), (override));
    MOCK_METHOD(void, eraseBlocks, (size_t idx, size_t num), (override));

    template <typename... Args>
    MockOrFakeDevice(Args&&... args) : device::Fake(std::forward<Args>(args)...)
    {
        ON_CALL(*this, readAt)
            .WillByDefault([this](std::span<std::byte> buf, size_t offset) {
                return device::Fake::readAt(buf, offset);
            });
        ON_CALL(*this, writeAt)
            .WillByDefault(
                [this](std::span<const std::byte> data, size_t offset) {
                    return device::Fake::writeAt(data, offset);
                });
        ON_CALL(*this, eraseBlocks)
            .WillByDefault([this](size_t idx, size_t num) {
                return device::Fake::eraseBlocks(idx, num);
            });
    }
};

inline file::Memory& fillFileInc(file::Memory& f, size_t off, size_t size)
{
    f.data.resize(size);
    for (size_t i = 0; i < size; ++i)
    {
        f.data[i] = static_cast<std::byte>(off + i);
    }
    return f;
}

template <typename Dev>
class OpTest : public testing::Test
{
  protected:
    OpTest() : d(fillFileInc(df, 0, 12), Device::Type::Nor, 4) {}

    file::Memory df, f;
    Dev d;
    NestedMutate m;
};

} // namespace ops
} // namespace flasher
