/*
 * 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/split_fiemap_writer.h>
#include <liblp/builder.h>
#include "libgsi/libgsi.h"

#include "gsi_installer.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 beginGsiInstall(const GsiInstallParams& params, 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 isGsiEnabled(bool* _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;
    binder::Status getInstalledGsiImageDir(std::string* _aidl_return) override;
    binder::Status wipeGsiUserdata(int* _aidl_return) override;

    // This is in GsiService, rather than GsiInstaller, since we need to access
    // it outside of the main lock which protects the unique_ptr.
    void StartAsyncOperation(const std::string& step, int64_t total_bytes);
    void UpdateProgress(int status, int64_t bytes_processed);

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

    // Helper methods for GsiInstaller.
    static std::string GetImagePath(const std::string& image_dir, const std::string& name);
    static bool RemoveGsiFiles(const std::string& install_dir, bool wipeUserdata);
    bool should_abort() const { return should_abort_; }

    static void RunStartupTasks();

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

    struct Image {
        std::unique_ptr<SplitFiemap> writer;
        uint64_t actual_size;
    };

    int ValidateInstallParams(GsiInstallParams* params);
    bool DisableGsiInstall();
    int ReenableGsi(bool one_shot);

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

    static std::string GetInstalledImagePath(const std::string& name);
    static std::string GetInstalledImageDir();

    std::mutex main_lock_;
    std::unique_ptr<GsiInstaller> installer_;

    // These are initialized or set in StartInstall().
    std::atomic<bool> should_abort_ = false;

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

}  // namespace gsi
}  // namespace android
