/*
 * Copyright (C) 2019 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.
 */
#pragma once

#include <map>
#include <memory>
#include <mutex>
#include <sstream>
#include <string>
#include <vector>

#include <android-base/unique_fd.h>
#include <android/gsi/BnGsiService.h>
#include <binder/BinderService.h>
#include <libfiemap_writer/fiemap_writer.h>
#include <liblp/builder.h>
#include "libgsi/libgsi.h"

namespace android {
namespace gsi {

class GsiService : public BinderService<GsiService>, public BnGsiService {
  public:
    static void Register();

    GsiService();
    ~GsiService() override;

    binder::Status startGsiInstall(int64_t gsiSize, int64_t userdataSize, bool wipeUserdata,
                                   int* _aidl_return) override;
    binder::Status commitGsiChunkFromStream(const ::android::os::ParcelFileDescriptor& stream,
                                            int64_t bytes, bool* _aidl_return) override;
    binder::Status getInstallProgress(::android::gsi::GsiProgress* _aidl_return) override;
    binder::Status commitGsiChunkFromMemory(const ::std::vector<uint8_t>& bytes,
                                            bool* _aidl_return) override;
    binder::Status cancelGsiInstall(bool* _aidl_return) override;
    binder::Status setGsiBootable(bool oneShot, int* _aidl_return) override;
    binder::Status removeGsiInstall(bool* _aidl_return) override;
    binder::Status disableGsiInstall(bool* _aidl_return) override;
    binder::Status isGsiRunning(bool* _aidl_return) override;
    binder::Status isGsiInstalled(bool* _aidl_return) override;
    binder::Status isGsiInstallInProgress(bool* _aidl_return) override;
    binder::Status getUserdataImageSize(int64_t* _aidl_return) override;
    binder::Status getGsiBootStatus(int* _aidl_return) override;

    static char const* getServiceName() { return kGsiServiceName; }

    static void RunStartupTasks();

  private:
    using LpMetadata = android::fs_mgr::LpMetadata;
    using MetadataBuilder = android::fs_mgr::MetadataBuilder;

    struct Image {
        android::fiemap_writer::FiemapUniquePtr writer;
        uint64_t actual_size;
    };
    using ImageMap = std::map<std::string, Image>;

    int StartInstall(int64_t gsi_size, int64_t userdata_size, bool wipe_userdata);
    int PerformSanityChecks();
    int PreallocateFiles();
    int PreallocateUserdata(ImageMap* partitions);
    int PreallocateSystem(ImageMap* partitions);
    bool FormatUserdata();
    bool CommitGsiChunk(int stream_fd, int64_t bytes);
    bool CommitGsiChunk(const void* data, size_t bytes);
    int SetGsiBootable(bool one_shot);
    int ReenableGsi(bool one_shot);
    bool DisableGsiInstall();
    bool AddPartitionFiemap(android::fs_mgr::MetadataBuilder* builder,
                            android::fs_mgr::Partition* partition, const Image& image);
    std::unique_ptr<LpMetadata> CreateMetadata(const ImageMap& partitions);
    fiemap_writer::FiemapUniquePtr CreateFiemapWriter(const std::string& path, uint64_t size,
                                                      int* error);
    bool CreateInstallStatusFile();
    bool CreateMetadataFile(const android::fs_mgr::LpMetadata& metadata);
    bool SetBootMode(bool one_shot);
    void PostInstallCleanup();

    void StartAsyncOperation(const std::string& step, int64_t total_bytes);
    void UpdateProgress(int status, int64_t bytes_processed);
    android::base::unique_fd OpenPartition(const std::string& name);
    int GetExistingImage(const LpMetadata& metadata, const std::string& name, Image* image);

    enum class AccessLevel {
        System,
        SystemOrShell
    };
    binder::Status CheckUid(AccessLevel level = AccessLevel::System);

    static bool RemoveGsiFiles(bool wipeUserdata);

    std::mutex main_lock_;

    // Set before installation starts, to determine whether or not to delete
    // the userdata image if installation fails.
    bool wipe_userdata_on_failure_;

    // These are initialized or set in StartInstall().
    bool installing_ = false;
    uint64_t userdata_block_size_;
    uint64_t system_block_size_;
    uint64_t gsi_size_;
    uint64_t userdata_size_;
    bool can_use_devicemapper_;
    bool wipe_userdata_;
    // Remaining data we're waiting to receive for the GSI image.
    uint64_t gsi_bytes_written_;

    // Progress bar state.
    std::mutex progress_lock_;
    GsiProgress progress_;

    android::base::unique_fd system_fd_;

    std::unique_ptr<LpMetadata> metadata_;
};

}  // namespace gsi
}  // namespace android
