/*
 * Copyright (C) 2018 The Android Open Source Project
 *
 * 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 <getopt.h>
#include <inttypes.h>
#include <sys/mount.h>
#include <sys/stat.h>
#include <sys/statvfs.h>
#include <sys/types.h>
#include <sysexits.h>
#include <unistd.h>

#include <algorithm>
#include <iostream>
#include <optional>
#include <regex>
#include <string>
#include <vector>

#include <android-base/parseint.h>
#include <android-base/properties.h>
#include <android-base/strings.h>
#ifdef __ANDROID__
#include <cutils/android_get_control_file.h>
#include <fs_mgr.h>
#include <libsnapshot/snapshot.h>
#endif
#include <jsonpb/jsonpb.h>
#include <liblp/builder.h>
#include <liblp/liblp.h>

#include "dynamic_partitions_device_info.pb.h"
using namespace android;
using namespace android::fs_mgr;

static int usage(int /* argc */, char* argv[], std::ostream& cerr) {
    cerr << argv[0]
         << " - command-line tool for dumping Android Logical Partition images.\n"
            "\n"
            "Usage:\n"
            "  "
         << argv[0]
         << " [-s <SLOT#>|--slot=<SLOT#>] [-j|--json] [FILE|DEVICE]\n"
            "\n"
            "Options:\n"
            "  -s, --slot=N     Slot number or suffix.\n"
            "  -j, --json       Print in JSON format.\n"
            "  -d, --dump-metadata-size\n"
            "                   Print the space reserved for metadata to stdout\n"
            "                   in bytes.\n"
            "  -a, --all        Dump all slots (not available in JSON mode).\n";
    return EX_USAGE;
}

static std::string BuildFlagString(const std::vector<std::string>& strings) {
    return strings.empty() ? "none" : android::base::Join(strings, ",");
}

static std::string BuildHeaderFlagString(uint32_t flags) {
    std::vector<std::string> strings;

    if (flags & LP_HEADER_FLAG_VIRTUAL_AB_DEVICE) {
        strings.emplace_back("virtual_ab_device");
        flags &= ~LP_HEADER_FLAG_VIRTUAL_AB_DEVICE;
    }

    for (uint32_t i = 0; i < sizeof(flags) * 8; i++) {
        if (!(flags & (1U << i))) {
            continue;
        }
        strings.emplace_back("unknown_flag_bit_" + std::to_string(i));
    }
    return BuildFlagString(strings);
}

static std::string BuildAttributeString(uint32_t attrs) {
    std::vector<std::string> strings;
    if (attrs & LP_PARTITION_ATTR_READONLY) strings.emplace_back("readonly");
    if (attrs & LP_PARTITION_ATTR_SLOT_SUFFIXED) strings.emplace_back("slot-suffixed");
    if (attrs & LP_PARTITION_ATTR_UPDATED) strings.emplace_back("updated");
    if (attrs & LP_PARTITION_ATTR_DISABLED) strings.emplace_back("disabled");
    return BuildFlagString(strings);
}

static std::string BuildGroupFlagString(uint32_t flags) {
    std::vector<std::string> strings;
    if (flags & LP_GROUP_SLOT_SUFFIXED) strings.emplace_back("slot-suffixed");
    return BuildFlagString(strings);
}

static std::string BuildBlockDeviceFlagString(uint32_t flags) {
    std::vector<std::string> strings;
    if (flags & LP_BLOCK_DEVICE_SLOT_SUFFIXED) strings.emplace_back("slot-suffixed");
    return BuildFlagString(strings);
}

// Reimplementation of fs_mgr_get_slot_suffix() without reading
// kernel commandline.
static std::string GetSlotSuffix() {
    return base::GetProperty("ro.boot.slot_suffix", "");
}

// Reimplementation of fs_mgr_get_super_partition_name() without reading
// kernel commandline. Always return the super partition at current slot.
static std::string GetSuperPartitionName(const std::optional<uint32_t>& slot = {}) {
    std::string super_partition = base::GetProperty("ro.boot.super_partition", "");
    if (super_partition.empty()) {
        return LP_METADATA_DEFAULT_PARTITION_NAME;
    }
    if (slot.has_value()) {
        return super_partition + SlotSuffixForSlotNumber(slot.value());
    }
    return super_partition + GetSlotSuffix();
}

static std::string RemoveSuffix(const std::string& s, const std::string& suffix) {
    if (base::EndsWith(s, suffix)) {
        return s.substr(0, s.length() - suffix.length());
    }
    return s;
}

// Merge proto with information from metadata.
static bool MergeMetadata(const LpMetadata* metadata,
                          DynamicPartitionsDeviceInfoProto* proto) {
    if (!metadata) return false;
    auto builder = MetadataBuilder::New(*metadata);
    if (!builder) return false;

    std::string slot_suffix = GetSlotSuffix();

    for (const auto& group_name : builder->ListGroups()) {
        auto group = builder->FindGroup(group_name);
        if (!group) continue;
        if (!base::EndsWith(group_name, slot_suffix)) continue;
        auto group_proto = proto->add_groups();
        group_proto->set_name(RemoveSuffix(group_name, slot_suffix));
        group_proto->set_maximum_size(group->maximum_size());

        for (auto partition : builder->ListPartitionsInGroup(group_name)) {
            auto partition_name = partition->name();
            if (!base::EndsWith(partition_name, slot_suffix)) continue;
            auto partition_proto = proto->add_partitions();
            partition_proto->set_name(RemoveSuffix(partition_name, slot_suffix));
            partition_proto->set_group_name(RemoveSuffix(group_name, slot_suffix));
            partition_proto->set_size(partition->size());
            partition_proto->set_is_dynamic(true);
        }
    }

    for (const auto& block_device : metadata->block_devices) {
        std::string name = GetBlockDevicePartitionName(block_device);
        BlockDeviceInfo info;
        if (!builder->GetBlockDeviceInfo(name, &info)) {
            continue;
        }
        auto block_device_proto = proto->add_block_devices();
        block_device_proto->set_name(RemoveSuffix(name, slot_suffix));
        block_device_proto->set_size(info.size);
        block_device_proto->set_block_size(info.logical_block_size);
        block_device_proto->set_alignment(info.alignment);
        block_device_proto->set_alignment_offset(info.alignment_offset);
    }

    auto super_device_proto = proto->mutable_super_device();
    super_device_proto->set_name(GetSuperPartitionName());
    super_device_proto->set_used_size(builder->UsedSpace());
    super_device_proto->set_total_size(GetTotalSuperPartitionSize(*metadata));

    return true;
}

#ifdef __ANDROID__
static DynamicPartitionsDeviceInfoProto::Partition* FindPartition(
        DynamicPartitionsDeviceInfoProto* proto, const std::string& partition) {
    for (DynamicPartitionsDeviceInfoProto::Partition& p : *proto->mutable_partitions()) {
        if (p.name() == partition) {
            return &p;
        }
    }
    return nullptr;
}

static std::optional<std::string> GetReadonlyPartitionName(const android::fs_mgr::FstabEntry& entry) {
    // Only report readonly partitions.
    if ((entry.flags & MS_RDONLY) == 0) return std::nullopt;
    std::regex regex("/([a-zA-Z_]*)$");
    std::smatch match;
    if (!std::regex_match(entry.mount_point, match, regex)) return std::nullopt;
    // On system-as-root devices, fstab lists / for system partition.
    std::string partition = match[1];
    return partition.empty() ? "system" : partition;
}

static bool MergeFsUsage(DynamicPartitionsDeviceInfoProto* proto,
                         std::ostream& cerr) {
    using namespace std::string_literals;
    Fstab fstab;
    if (!ReadDefaultFstab(&fstab)) {
        cerr << "Cannot read fstab\n";
        return false;
    }

    for (const auto& entry : fstab) {
        auto partition = GetReadonlyPartitionName(entry);
        if (!partition) {
            continue;
        }

        // system is mounted to "/";
        const char* mount_point = (entry.mount_point == "/system")
            ? "/" : entry.mount_point.c_str();

        struct statvfs vst;
        if (statvfs(mount_point, &vst) == -1) {
            continue;
        }

        auto partition_proto = FindPartition(proto, *partition);
        if (partition_proto == nullptr) {
            partition_proto = proto->add_partitions();
            partition_proto->set_name(*partition);
            partition_proto->set_is_dynamic(false);
        }
        partition_proto->set_fs_size((uint64_t)vst.f_blocks * vst.f_frsize);

        if (!entry.fs_type.empty()) {
            partition_proto->set_fs_type(entry.fs_type);
        } else {
            partition_proto->set_fs_type("UNKNOWN");
        }

        if (vst.f_bavail <= vst.f_blocks) {
            partition_proto->set_fs_used((uint64_t)(vst.f_blocks - vst.f_bavail) * vst.f_frsize);
        }
    }
    return true;
}
static void DumpSnapshotState(std::ostream& output) {
    if (android::base::GetBoolProperty("ro.virtual_ab.enabled", false)) {
        if (auto sm = android::snapshot::SnapshotManager::New()) {
            output << "---------------\n";
            output << "Snapshot state:\n";
            output << "---------------\n";
            sm->Dump(output);
        }
    }
}
#endif

// Print output in JSON format.
// If successful, this function must write a valid JSON string to "cout" and return 0.
static int PrintJson(const LpMetadata* metadata, std::ostream& cout,
                     std::ostream& cerr) {
    DynamicPartitionsDeviceInfoProto proto;

    if (base::GetBoolProperty("ro.boot.dynamic_partitions", false)) {
        proto.set_enabled(true);
    }

    if (base::GetBoolProperty("ro.boot.dynamic_partitions_retrofit", false)) {
        proto.set_retrofit(true);
    }

    if (!MergeMetadata(metadata, &proto)) {
        cerr << "Warning: Failed to read metadata.\n";
    }
#ifdef __ANDROID__
    if (!MergeFsUsage(&proto, cerr)) {
        cerr << "Warning: Failed to read filesystem size and usage.\n";
    }
#endif

    auto error_or_json = jsonpb::MessageToJsonString(proto);
    if (!error_or_json.ok()) {
        cerr << error_or_json.error() << "\n";
        return EX_SOFTWARE;
    }
    cout << *error_or_json;
    return EX_OK;
}

static int DumpMetadataSize(const LpMetadata& metadata, std::ostream& cout) {
    auto super_device = GetMetadataSuperBlockDevice(metadata);
    uint64_t metadata_size = super_device->first_logical_sector * LP_SECTOR_SIZE;
    cout << metadata_size << std::endl;
    return EX_OK;
}

class FileOrBlockDeviceOpener final : public PartitionOpener {
public:
    android::base::unique_fd Open(const std::string& path, int flags) const override {
        // Try a local file first.
        android::base::unique_fd fd;

#ifdef __ANDROID__
        fd.reset(android_get_control_file(path.c_str()));
        if (fd >= 0) return fd;
#endif
        fd.reset(open(path.c_str(), flags));
        if (fd >= 0) return fd;

        return PartitionOpener::Open(path, flags);
    }
};

std::optional<std::tuple<std::string, uint64_t>>
ParseLinearExtentData(const LpMetadata& pt, const LpMetadataExtent& extent) {
    if (extent.target_type != LP_TARGET_TYPE_LINEAR) {
        return std::nullopt;
    }
    const auto& block_device = pt.block_devices[extent.target_source];
    std::string device_name = GetBlockDevicePartitionName(block_device);
    return std::make_tuple(std::move(device_name), extent.target_data);
}

static void PrintMetadata(const LpMetadata& pt, std::ostream& cout) {
    cout << "Metadata version: " << pt.header.major_version << "." << pt.header.minor_version
         << "\n";
    cout << "Metadata size: " << (pt.header.header_size + pt.header.tables_size) << " bytes\n";
    cout << "Metadata max size: " << pt.geometry.metadata_max_size << " bytes\n";
    cout << "Metadata slot count: " << pt.geometry.metadata_slot_count << "\n";
    cout << "Header flags: " << BuildHeaderFlagString(pt.header.flags) << "\n";
    cout << "Partition table:\n";
    cout << "------------------------\n";

    std::vector<std::tuple<std::string, const LpMetadataExtent*>> extents;

    for (const auto& partition : pt.partitions) {
        std::string name = GetPartitionName(partition);
        std::string group_name = GetPartitionGroupName(pt.groups[partition.group_index]);
        cout << "  Name: " << name << "\n";
        cout << "  Group: " << group_name << "\n";
        cout << "  Attributes: " << BuildAttributeString(partition.attributes) << "\n";
        cout << "  Extents:\n";
        uint64_t first_sector = 0;
        for (size_t i = 0; i < partition.num_extents; i++) {
            const LpMetadataExtent& extent = pt.extents[partition.first_extent_index + i];
            cout << "    " << first_sector << " .. " << (first_sector + extent.num_sectors - 1)
                 << " ";
            first_sector += extent.num_sectors;
            if (extent.target_type == LP_TARGET_TYPE_LINEAR) {
                const auto& block_device = pt.block_devices[extent.target_source];
                std::string device_name = GetBlockDevicePartitionName(block_device);
                cout << "linear " << device_name.c_str() << " " << extent.target_data;
            } else if (extent.target_type == LP_TARGET_TYPE_ZERO) {
                cout << "zero";
            }
            extents.push_back(std::make_tuple(name, &extent));
            cout << "\n";
        }
        cout << "------------------------\n";
    }

    std::sort(extents.begin(), extents.end(), [&](const auto& x, const auto& y) {
        auto x_data = ParseLinearExtentData(pt, *std::get<1>(x));
        auto y_data = ParseLinearExtentData(pt, *std::get<1>(y));
        return x_data < y_data;
    });

    cout << "Super partition layout:\n";
    cout << "------------------------\n";
    for (auto&& [name, extent] : extents) {
        auto data = ParseLinearExtentData(pt, *extent);
        if (!data) continue;
        auto&& [block_device, offset] = *data;
        cout << block_device << ": " << offset << " .. " << (offset + extent->num_sectors)
             << ": " << name << " (" << extent->num_sectors << " sectors)\n";
    }
    cout << "------------------------\n";

    cout << "Block device table:\n";
    cout << "------------------------\n";
    for (const auto& block_device : pt.block_devices) {
        std::string partition_name = GetBlockDevicePartitionName(block_device);
        cout << "  Partition name: " << partition_name << "\n";
        cout << "  First sector: " << block_device.first_logical_sector << "\n";
        cout << "  Size: " << block_device.size << " bytes\n";
        cout << "  Flags: " << BuildBlockDeviceFlagString(block_device.flags) << "\n";
        cout << "------------------------\n";
    }

    cout << "Group table:\n";
    cout << "------------------------\n";
    for (const auto& group : pt.groups) {
        std::string group_name = GetPartitionGroupName(group);
        cout << "  Name: " << group_name << "\n";
        cout << "  Maximum size: " << group.maximum_size << " bytes\n";
        cout << "  Flags: " << BuildGroupFlagString(group.flags) << "\n";
        cout << "------------------------\n";
    }
}

static std::unique_ptr<LpMetadata> ReadDeviceOrFile(const std::string& path, uint32_t slot) {
    if (IsEmptySuperImage(path)) {
        return ReadFromImageFile(path);
    }
    return ReadMetadata(path, slot);
}

int LpdumpMain(int argc, char* argv[], std::ostream& cout, std::ostream& cerr) {
    // clang-format off
    struct option options[] = {
        { "all", no_argument, nullptr, 'a' },
        { "slot", required_argument, nullptr, 's' },
        { "help", no_argument, nullptr, 'h' },
        { "json", no_argument, nullptr, 'j' },
        { "dump-metadata-size", no_argument, nullptr, 'd' },
        { "is-super-empty", no_argument, nullptr, 'e' },
        { nullptr, 0, nullptr, 0 },
    };
    // clang-format on

    // Allow this function to be invoked by lpdumpd multiple times.
    optind = 1;

    int rv;
    int index;
    bool json = false;
    bool dump_metadata_size = false;
    bool dump_all = false;
    std::optional<uint32_t> slot;
    while ((rv = getopt_long_only(argc, argv, "s:jhde", options, &index)) != -1) {
        switch (rv) {
            case 'a':
                dump_all = true;
                break;
            case 'h':
                usage(argc, argv, cout);
                return EX_OK;
            case 's': {
                uint32_t slot_arg;
                if (android::base::ParseUint(optarg, &slot_arg)) {
                    slot = slot_arg;
                } else {
                    slot = SlotNumberForSlotSuffix(optarg);
                }
                break;
            }
            case 'e':
                // This is ignored, we now derive whether it's empty automatically.
                break;
            case 'd':
                dump_metadata_size = true;
                break;
            case 'j':
                json = true;
                break;
            case '?':
            case ':':
                return usage(argc, argv, cerr);
        }
    }

    if (dump_all) {
        if (slot.has_value()) {
            cerr << "Cannot specify both --all and --slot.\n";
            return usage(argc, argv, cerr);
        }
        if (json) {
            cerr << "Cannot specify both --all and --json.\n";
            return usage(argc, argv, cerr);
        }

        // When dumping everything always start from the first slot.
        slot = 0;
    }

#ifdef __ANDROID__
    // Use the current slot as a default for A/B devices.
    auto current_slot_suffix = GetSlotSuffix();
    if (!slot.has_value() && !current_slot_suffix.empty()) {
        slot = SlotNumberForSlotSuffix(current_slot_suffix);
    }
#endif

    // If we still haven't determined a slot yet, use the first one.
    if (!slot.has_value()) {
        slot = 0;
    }

    // Determine the path to the super partition (or image). If an explicit
    // path is given, we use it for everything. Otherwise, we will infer it
    // at the time we need to read metadata.
    std::string super_path;
    bool override_super_name = (optind < argc);
    if (override_super_name) {
        super_path = argv[optind++];
    } else {
#ifdef __ANDROID__
        super_path = GetSuperPartitionName(slot);
#else
        cerr << "Must specify a super partition image.\n";
        return usage(argc, argv, cerr);
#endif
    }

    auto pt = ReadDeviceOrFile(super_path, slot.value());

    // --json option doesn't require metadata to be present.
    if (json) {
        return PrintJson(pt.get(), cout, cerr);
    }

    if (!pt) {
        cerr << "Failed to read metadata.\n";
        return EX_NOINPUT;
    }

    if (dump_metadata_size) {
        return DumpMetadataSize(*pt.get(), cout);
    }

    // When running on the device, we can check the slot count. Otherwise we
    // use the # of metadata slots. (There is an extra slot we don't want to
    // dump because it is currently unused.)
#ifdef __ANDROID__
    uint32_t num_slots = current_slot_suffix.empty() ? 1 : 2;
    if (dump_all && num_slots > 1) {
        cout << "Current slot: " << current_slot_suffix << "\n";
    }
#else
    uint32_t num_slots = pt->geometry.metadata_slot_count;
#endif
    // Empty images only have one slot.
    if (IsEmptySuperImage(super_path)) {
        num_slots = 1;
    }

    if (num_slots > 1) {
        cout << "Slot " << slot.value() << ":\n";
    }
    PrintMetadata(*pt.get(), cout);

    if (dump_all) {
        for (uint32_t i = 1; i < num_slots; i++) {
            if (!override_super_name) {
                super_path = GetSuperPartitionName(i);
            }

            pt = ReadDeviceOrFile(super_path, i);
            if (!pt) {
                continue;
            }

            cout << "\nSlot " << i << ":\n";
            PrintMetadata(*pt.get(), cout);
        }
    }
#ifdef __ANDROID__
    DumpSnapshotState(cout);
#endif

    return EX_OK;
}

int LpdumpMain(int argc, char* argv[]) {
    return LpdumpMain(argc, argv, std::cout, std::cerr);
}
