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

#include <flasher/logging.hpp>
#include <flasher/ops.hpp>
#include <stdplus/exception.hpp>

#include <algorithm>
#include <cstddef>
#include <format>
#include <stdexcept>
#include <vector>

namespace flasher
{
namespace ops
{

void read(Device& dev, size_t dev_offset, File& file, size_t file_offset,
          Mutate& mutate, size_t max_size, std::optional<size_t> stride_size)
{
    if (dev_offset > dev.getSize())
    {
        throw std::invalid_argument(std::format(
            "Device smaller than offset, {} < {}", dev.getSize(), dev_offset));
    }
    size_t stride = stride_size ? *stride_size : dev.recommendedStride();
    if (stride == 0)
    {
        throw std::invalid_argument("Stride cannot be 0");
    }
    std::vector<std::byte> dev_buf_v(stride * 2);
    const std::span<std::byte> dev_buf(dev_buf_v);
    std::span<std::byte> dev_data;
    max_size = std::min(max_size, dev.getSize() - dev_offset);
    while (max_size > 0)
    {
        while (dev_data.size() < stride && max_size > dev_data.size())
        {
            auto new_size = std::min(stride, max_size - dev_data.size());
            auto new_dev_data = dev.readAt(
                dev_buf.subspan(dev_data.size(), new_size), dev_offset);
            LOG(LogLevel::Info, " RD@{}#{}", dev_offset, new_dev_data.size());
            mutate.reverse(new_dev_data, dev_offset);
            dev_data =
                dev_buf.subspan(0, dev_data.size() + new_dev_data.size());
            dev_offset += new_dev_data.size();
        }
        auto written = file.writeAt(dev_data, file_offset);
        LOG(LogLevel::Info, " WF@{}#{}", file_offset, written.size());
        file_offset += written.size();
        std::memmove(dev_data.data(), dev_data.data() + written.size(),
                     dev_data.size() - written.size());
        dev_data = dev_data.subspan(0, dev_data.size() - written.size());
        max_size -= written.size();
    }
    LOG(LogLevel::Info, "\n");
}

} // namespace ops
} // namespace flasher
