/*
 * 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 <android/content/pm/BnDataLoaderStatusListener.h>
#include <android/content/pm/DataLoaderParamsParcel.h>
#include <android/content/pm/FileSystemControlParcel.h>
#include <android/content/pm/IDataLoaderStatusListener.h>
#include <android/os/incremental/BnIncrementalServiceConnector.h>
#include <android/os/incremental/BnStorageHealthListener.h>
#include <android/os/incremental/BnStorageLoadingProgressListener.h>
#include <android/os/incremental/PerUidReadTimeouts.h>
#include <android/os/incremental/StorageHealthCheckParams.h>
#include <binder/IAppOpsCallback.h>
#include <utils/String16.h>
#include <utils/StrongPointer.h>
#include <ziparchive/zip_archive.h>

#include <atomic>
#include <chrono>
#include <condition_variable>
#include <functional>
#include <limits>
#include <map>
#include <mutex>
#include <set>
#include <span>
#include <string>
#include <string_view>
#include <thread>
#include <unordered_map>
#include <unordered_set>
#include <utility>
#include <vector>

#include "ServiceWrappers.h"
#include "incfs.h"
#include "path.h"

namespace android::incremental {

using MountId = int;
using StorageId = int;
using FileId = incfs::FileId;
using BlockIndex = incfs::BlockIndex;
using RawMetadata = incfs::RawMetadata;
using Seconds = std::chrono::seconds;
using BootClockTsUs = uint64_t;

using IDataLoaderStatusListener = ::android::content::pm::IDataLoaderStatusListener;
using DataLoaderStatusListener = ::android::sp<IDataLoaderStatusListener>;

using StorageHealthCheckParams = ::android::os::incremental::StorageHealthCheckParams;
using IStorageHealthListener = ::android::os::incremental::IStorageHealthListener;
using StorageHealthListener = ::android::sp<IStorageHealthListener>;
using IStorageLoadingProgressListener = ::android::os::incremental::IStorageLoadingProgressListener;
using StorageLoadingProgressListener = ::android::sp<IStorageLoadingProgressListener>;

using PerUidReadTimeouts = ::android::os::incremental::PerUidReadTimeouts;

class IncrementalService final {
public:
    explicit IncrementalService(ServiceManagerWrapper&& sm, std::string_view rootDir);

#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wnon-virtual-dtor"
    ~IncrementalService();
#pragma GCC diagnostic pop

    static constexpr StorageId kInvalidStorageId = -1;
    static constexpr StorageId kMaxStorageId = std::numeric_limits<int>::max();

    static constexpr BootClockTsUs kMaxBootClockTsUs = std::numeric_limits<BootClockTsUs>::max();

    enum CreateOptions {
        TemporaryBind = 1,
        PermanentBind = 2,
        CreateNew = 4,
        OpenExisting = 8,

        Default = TemporaryBind | CreateNew
    };

    enum class BindKind {
        Temporary = 0,
        Permanent = 1,
    };

    enum StorageFlags {
        ReadLogsAllowed = 1 << 0,
        ReadLogsEnabled = 1 << 1,
    };

    struct LoadingProgress {
        ssize_t filledBlocks;
        ssize_t totalBlocks;

        bool isError() const { return totalBlocks < 0; }
        bool started() const { return totalBlocks > 0; }
        bool fullyLoaded() const { return !isError() && (totalBlocks == filledBlocks); }

        int blocksRemainingOrError() const {
            return totalBlocks <= 0 ? totalBlocks : totalBlocks - filledBlocks;
        }

        float getProgress() const {
            return totalBlocks < 0
                    ? totalBlocks
                    : totalBlocks > 0 ? double(filledBlocks) / double(totalBlocks) : 1.f;
        }
    };

    static FileId idFromMetadata(std::span<const uint8_t> metadata);
    static inline FileId idFromMetadata(std::span<const char> metadata) {
        return idFromMetadata({(const uint8_t*)metadata.data(), metadata.size()});
    }

    void onDump(int fd);

    void onSystemReady();

    StorageId createStorage(std::string_view mountPoint,
                            const content::pm::DataLoaderParamsParcel& dataLoaderParams,
                            CreateOptions options);
    StorageId createLinkedStorage(std::string_view mountPoint, StorageId linkedStorage,
                                  CreateOptions options = CreateOptions::Default);
    StorageId openStorage(std::string_view path);

    bool startLoading(StorageId storage, content::pm::DataLoaderParamsParcel&& dataLoaderParams,
                      const DataLoaderStatusListener& statusListener,
                      StorageHealthCheckParams&& healthCheckParams,
                      const StorageHealthListener& healthListener,
                      const std::vector<PerUidReadTimeouts>& perUidReadTimeouts);

    int bind(StorageId storage, std::string_view source, std::string_view target, BindKind kind);
    int unbind(StorageId storage, std::string_view target);
    void deleteStorage(StorageId storage);

    void disallowReadLogs(StorageId storage);
    int setStorageParams(StorageId storage, bool enableReadLogs);

    int makeFile(StorageId storage, std::string_view path, int mode, FileId id,
                 incfs::NewFileParams params, std::span<const uint8_t> data);
    int makeDir(StorageId storage, std::string_view path, int mode = 0755);
    int makeDirs(StorageId storage, std::string_view path, int mode = 0755);

    int link(StorageId sourceStorageId, std::string_view oldPath, StorageId destStorageId,
             std::string_view newPath);
    int unlink(StorageId storage, std::string_view path);

    int isFileFullyLoaded(StorageId storage, std::string_view filePath) const;

    LoadingProgress getLoadingProgress(StorageId storage, bool stopOnFirstIncomplete) const;

    bool registerLoadingProgressListener(StorageId storage,
                                         const StorageLoadingProgressListener& progressListener);
    bool unregisterLoadingProgressListener(StorageId storage);
    bool registerStorageHealthListener(StorageId storage,
                                       StorageHealthCheckParams&& healthCheckParams,
                                       const StorageHealthListener& healthListener);
    void unregisterStorageHealthListener(StorageId storage);
    RawMetadata getMetadata(StorageId storage, std::string_view path) const;
    RawMetadata getMetadata(StorageId storage, FileId node) const;

    bool configureNativeBinaries(StorageId storage, std::string_view apkFullPath,
                                 std::string_view libDirRelativePath, std::string_view abi,
                                 bool extractNativeLibs);
    bool waitForNativeBinariesExtraction(StorageId storage);

    class AppOpsListener : public android::BnAppOpsCallback {
    public:
        AppOpsListener(IncrementalService& incrementalService, std::string packageName)
              : incrementalService(incrementalService), packageName(std::move(packageName)) {}
        void opChanged(int32_t op, const String16& packageName) final;

    private:
        IncrementalService& incrementalService;
        const std::string packageName;
    };

    class IncrementalServiceConnector : public os::incremental::BnIncrementalServiceConnector {
    public:
        IncrementalServiceConnector(IncrementalService& incrementalService, int32_t storage)
              : incrementalService(incrementalService), storage(storage) {}
        binder::Status setStorageParams(bool enableReadLogs, int32_t* _aidl_return) final;

    private:
        IncrementalService& incrementalService;
        int32_t const storage;
    };

private:
    struct IncFsMount;

    class DataLoaderStub : public content::pm::BnDataLoaderStatusListener {
    public:
        DataLoaderStub(IncrementalService& service, MountId id,
                       content::pm::DataLoaderParamsParcel&& params,
                       content::pm::FileSystemControlParcel&& control,
                       const DataLoaderStatusListener* statusListener,
                       StorageHealthCheckParams&& healthCheckParams,
                       const StorageHealthListener* healthListener, std::string&& healthPath);
        ~DataLoaderStub();
        // Cleans up the internal state and invalidates DataLoaderStub. Any subsequent calls will
        // result in an error.
        void cleanupResources();

        bool requestCreate();
        bool requestStart();
        bool requestDestroy();

        void onDump(int fd);

        MountId id() const { return mId.load(std::memory_order_relaxed); }
        const content::pm::DataLoaderParamsParcel& params() const { return mParams; }
        void setHealthListener(StorageHealthCheckParams&& healthCheckParams,
                               const StorageHealthListener* healthListener);

    private:
        binder::Status onStatusChanged(MountId mount, int newStatus) final;
        binder::Status reportStreamHealth(MountId mount, int newStatus) final;

        sp<content::pm::IDataLoader> getDataLoader();

        bool bind();
        bool create();
        bool start();
        bool destroy();

        bool setTargetStatus(int status);
        void setTargetStatusLocked(int status);

        bool fsmStep();
        bool fsmStep(int currentStatus, int targetStatus);

        void onHealthStatus(StorageHealthListener healthListener, int healthStatus);
        void updateHealthStatus(bool baseline = false);

        bool isValid() const { return id() != kInvalidStorageId; }

        bool isHealthParamsValid() const;

        const incfs::UniqueControl& initializeHealthControl();
        void resetHealthControl();

        BootClockTsUs getOldestPendingReadTs();

        void registerForPendingReads();
        void unregisterFromPendingReads();

        IncrementalService& mService;

        std::mutex mMutex;
        std::atomic<MountId> mId = kInvalidStorageId;
        content::pm::DataLoaderParamsParcel mParams;
        content::pm::FileSystemControlParcel mControl;
        DataLoaderStatusListener mStatusListener;
        StorageHealthListener mHealthListener;

        std::condition_variable mStatusCondition;
        int mCurrentStatus = content::pm::IDataLoaderStatusListener::DATA_LOADER_DESTROYED;
        int mTargetStatus = content::pm::IDataLoaderStatusListener::DATA_LOADER_DESTROYED;
        TimePoint mTargetStatusTs = {};

        std::string mHealthPath;
        incfs::UniqueControl mHealthControl;
        struct {
            TimePoint userTs;
            BootClockTsUs kernelTsUs;
        } mHealthBase = {TimePoint::max(), kMaxBootClockTsUs};
        StorageHealthCheckParams mHealthCheckParams;
        int mStreamStatus = content::pm::IDataLoaderStatusListener::STREAM_HEALTHY;
        std::vector<incfs::ReadInfo> mLastPendingReads;
    };
    using DataLoaderStubPtr = sp<DataLoaderStub>;

    struct IncFsMount {
        struct Bind {
            StorageId storage;
            std::string savedFilename;
            std::string sourceDir;
            BindKind kind;
        };

        struct Storage {
            std::string name;
        };

        using Control = incfs::UniqueControl;

        using BindMap = std::map<std::string, Bind, path::PathLess>;
        using StorageMap = std::unordered_map<StorageId, Storage>;

        mutable std::mutex lock;
        const std::string root;
        Control control;
        /*const*/ MountId mountId;
        int32_t flags = StorageFlags::ReadLogsAllowed;
        StorageMap storages;
        BindMap bindPoints;
        DataLoaderStubPtr dataLoaderStub;
        std::atomic<int> nextStorageDirNo{0};
        const IncrementalService& incrementalService;

        IncFsMount(std::string root, MountId mountId, Control control,
                   const IncrementalService& incrementalService)
              : root(std::move(root)),
                control(std::move(control)),
                mountId(mountId),
                incrementalService(incrementalService) {}
        IncFsMount(IncFsMount&&) = delete;
        IncFsMount& operator=(IncFsMount&&) = delete;
        ~IncFsMount();

        StorageMap::iterator makeStorage(StorageId id);

        void disallowReadLogs() { flags &= ~StorageFlags::ReadLogsAllowed; }
        int32_t readLogsAllowed() const { return (flags & StorageFlags::ReadLogsAllowed); }

        void setReadLogsEnabled(bool value) {
            if (value)
                flags |= StorageFlags::ReadLogsEnabled;
            else
                flags &= ~StorageFlags::ReadLogsEnabled;
        }
        int32_t readLogsEnabled() const { return (flags & StorageFlags::ReadLogsEnabled); }

        static void cleanupFilesystem(std::string_view root);
    };

    using IfsMountPtr = std::shared_ptr<IncFsMount>;
    using MountMap = std::unordered_map<MountId, IfsMountPtr>;
    using BindPathMap = std::map<std::string, IncFsMount::BindMap::iterator, path::PathLess>;

    static bool perfLoggingEnabled();

    void setUidReadTimeouts(StorageId storage,
                            const std::vector<PerUidReadTimeouts>& perUidReadTimeouts);
    void clearUidReadTimeouts(StorageId storage);
    void updateUidReadTimeouts(StorageId storage, Clock::time_point timeLimit);

    std::unordered_set<std::string_view> adoptMountedInstances();
    void mountExistingImages(const std::unordered_set<std::string_view>& mountedRootNames);
    bool mountExistingImage(std::string_view root);

    IfsMountPtr getIfs(StorageId storage) const;
    const IfsMountPtr& getIfsLocked(StorageId storage) const;
    int addBindMount(IncFsMount& ifs, StorageId storage, std::string_view storageRoot,
                     std::string&& source, std::string&& target, BindKind kind,
                     std::unique_lock<std::mutex>& mainLock);

    int addBindMountWithMd(IncFsMount& ifs, StorageId storage, std::string&& metadataName,
                           std::string&& source, std::string&& target, BindKind kind,
                           std::unique_lock<std::mutex>& mainLock);

    void addBindMountRecordLocked(IncFsMount& ifs, StorageId storage, std::string&& metadataName,
                                  std::string&& source, std::string&& target, BindKind kind);

    DataLoaderStubPtr prepareDataLoader(IncFsMount& ifs,
                                        content::pm::DataLoaderParamsParcel&& params,
                                        const DataLoaderStatusListener* statusListener = nullptr,
                                        StorageHealthCheckParams&& healthCheckParams = {},
                                        const StorageHealthListener* healthListener = nullptr);
    void prepareDataLoaderLocked(IncFsMount& ifs, content::pm::DataLoaderParamsParcel&& params,
                                 const DataLoaderStatusListener* statusListener = nullptr,
                                 StorageHealthCheckParams&& healthCheckParams = {},
                                 const StorageHealthListener* healthListener = nullptr);

    BindPathMap::const_iterator findStorageLocked(std::string_view path) const;
    StorageId findStorageId(std::string_view path) const;

    void deleteStorage(IncFsMount& ifs);
    void deleteStorageLocked(IncFsMount& ifs, std::unique_lock<std::mutex>&& ifsLock);
    MountMap::iterator getStorageSlotLocked();
    std::string normalizePathToStorage(const IncFsMount& incfs, StorageId storage,
                                       std::string_view path) const;
    std::string normalizePathToStorageLocked(const IncFsMount& incfs,
                                             IncFsMount::StorageMap::const_iterator storageIt,
                                             std::string_view path) const;
    int makeDirs(const IncFsMount& ifs, StorageId storageId, std::string_view path, int mode);
    binder::Status applyStorageParams(IncFsMount& ifs, bool enableReadLogs);

    int isFileFullyLoadedFromPath(const IncFsMount& ifs, std::string_view filePath) const;
    LoadingProgress getLoadingProgressFromPath(const IncFsMount& ifs, std::string_view path,
                                               bool stopOnFirstIncomplete) const;

    int setFileContent(const IfsMountPtr& ifs, const incfs::FileId& fileId,
                       std::string_view debugFilePath, std::span<const uint8_t> data) const;

    void registerAppOpsCallback(const std::string& packageName);
    bool unregisterAppOpsCallback(const std::string& packageName);
    void onAppOpChanged(const std::string& packageName);

    void runJobProcessing();
    void extractZipFile(const IfsMountPtr& ifs, ZipArchiveHandle zipFile, ZipEntry& entry,
                        const incfs::FileId& libFileId, std::string_view debugLibPath,
                        Clock::time_point scheduledTs);

    void runCmdLooper();

    bool addTimedJob(TimedQueueWrapper& timedQueue, MountId id, Milliseconds after, Job what);
    bool removeTimedJobs(TimedQueueWrapper& timedQueue, MountId id);
    bool updateLoadingProgress(int32_t storageId,
                               const StorageLoadingProgressListener& progressListener);

private:
    const std::unique_ptr<VoldServiceWrapper> mVold;
    const std::unique_ptr<DataLoaderManagerWrapper> mDataLoaderManager;
    const std::unique_ptr<IncFsWrapper> mIncFs;
    const std::unique_ptr<AppOpsManagerWrapper> mAppOpsManager;
    const std::unique_ptr<JniWrapper> mJni;
    const std::unique_ptr<LooperWrapper> mLooper;
    const std::unique_ptr<TimedQueueWrapper> mTimedQueue;
    const std::unique_ptr<TimedQueueWrapper> mProgressUpdateJobQueue;
    const std::unique_ptr<FsWrapper> mFs;
    const std::string mIncrementalDir;

    mutable std::mutex mLock;
    mutable std::mutex mMountOperationLock;
    MountMap mMounts;
    BindPathMap mBindsByPath;

    std::mutex mCallbacksLock;
    std::map<std::string, sp<AppOpsListener>> mCallbackRegistered;

    std::atomic_bool mSystemReady = false;
    StorageId mNextId = 0;

    std::atomic_bool mRunning{true};

    std::unordered_map<MountId, std::vector<Job>> mJobQueue;
    MountId mPendingJobsMount = kInvalidStorageId;
    std::condition_variable mJobCondition;
    std::mutex mJobMutex;
    std::thread mJobProcessor;

    std::thread mCmdLooperThread;
};

} // namespace android::incremental
