// 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/file.hpp>
#include <flasher/mod.hpp>
#include <flasher/ops.hpp>
#include <flashupdate/args.hpp>
#include <flashupdate/flash.hpp>
#include <flashupdate/ops.hpp>
#include <flashupdate/reader/copy.hpp>

#include <filesystem>
#include <string>

namespace flashupdate
{
namespace ops
{

using flasher::ModArgs;
using stdplus::fd::OpenAccess;
using stdplus::fd::OpenFlag;
using stdplus::fd::OpenFlags;

void copyPartition(const Args& args)
{
    if (args.fromPartition == std::nullopt)
    {
        throw std::runtime_error("cannot read from active/primary partition");
    }

    auto& flashHelper = args.flashHelper;
    auto flash = flashHelper->getFlash(args.fromPartition);
    if (!flash)
    {
        throw std::runtime_error("failed to find Flash fromPartition");
    }

    std::string fromFlashDev(flash->first);
    auto fromDevMod = ModArgs(fromFlashDev);
    fromFlashDev = fromDevMod.arr.back();
    auto fromDev = flasher::openDevice(fromDevMod);
    auto reader = reader::Copy(*fromDev);
    fromDev.reset();

    // Verify that the target partition is also available
    flash = flashHelper->getFlash(args.toPartition, reader.getSize());
    if (!flash)
    {
        throw std::runtime_error("failed to find Flash toPartition");
    }

    // toFlashDev will be fetched with getFlash() which uses the args.primary
    // and args.stagingIndex to target the toPartition directly.
    // fromPartition.value() to point to it directly. Just pass in the fromDev
    // input and it will work automatically.
    writeHelper(args, fromFlashDev, reader);
}

} // namespace ops
} // namespace flashupdate
