// 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 <fcntl.h>
#include <mtd/mtd-user.h>
#include <sys/ioctl.h>

#include <flasher/device/mtd.hpp>
#include <flasher/util.hpp>
#include <stdplus/fd/create.hpp>
#include <stdplus/print.hpp>

#include <cstring>
#include <format>
#include <stdexcept>
#include <utility>

namespace flasher
{
namespace device
{

using stdplus::fd::Whence;

Mtd::Mtd(stdplus::ManagedFd&& fd) :
    Device(buildDeviceInfo(fd)), fd(std::move(fd)),
    offset(this->fd.lseek(0, Whence::Cur))
{}

std::span<std::byte> Mtd::readAt(std::span<std::byte> buf, size_t offset)
{
    return opAt(&stdplus::Fd::read, fd, this->offset, buf, offset);
}

std::span<const std::byte> Mtd::writeAt(std::span<const std::byte> data,
                                        size_t offset)
{
    return opAt(&stdplus::Fd::write, fd, this->offset, data, offset);
}

void Mtd::eraseBlocks(size_t idx, size_t num)
{
    struct erase_info_user erase;
    memset(&erase, 0, sizeof(erase));
    auto erase_size = getEraseSize();
    erase.length = erase_size * num;
    erase.start = erase_size * idx;
    fd.ioctl(MEMERASE, &erase);
}

Device::DeviceInfo Mtd::buildDeviceInfo(stdplus::Fd& fd)
{
    mtd_info_t info;
    fd.ioctl(MEMGETINFO, &info);

    DeviceInfo ret;
    switch (info.type)
    {
        case MTD_NORFLASH:
            ret.type = Type::Nor;
            break;
        default:
            throw std::invalid_argument(
                std::format("Unknown MTD type {:#x}", info.type));
    }
    ret.size = info.size;
    ret.erase_size = info.erasesize;
    return ret;
}

class MtdType : public DeviceType
{
  public:
    std::unique_ptr<Device> open(const ModArgs& args) override
    {
        if (args.arr.size() != 2)
        {
            throw std::invalid_argument("Requires a single file argument");
        }
        return std::make_unique<Mtd>(stdplus::fd::open(
            args.arr[1].c_str(),
            stdplus::fd::OpenFlags(stdplus::fd::OpenAccess::ReadWrite)));
    }

    void printHelp() const override
    {
        stdplus::println(stderr, "  `mtd` device");
        stdplus::println(stderr,
                         "    FILE             required  MTD device filename");
    }
};

void registerMtd() __attribute__((constructor));
void registerMtd()
{
    registerDeviceType("mtd", std::make_unique<MtdType>());
}

void unregisterMtd() __attribute__((destructor));
void unregisterMtd()
{
    unregisterDeviceType("mtd");
}

} // namespace device
} // namespace flasher
