/*
 * Copyright (C) 2017 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 "fs/Vfat.h"
#include "Devmapper.h"
#include "Loop.h"
#include "ObbVolume.h"
#include "Utils.h"
#include "VoldUtil.h"

#include <android-base/logging.h>
#include <android-base/stringprintf.h>
#include <android-base/unique_fd.h>
#include <cutils/fs.h>
#include <private/android_filesystem_config.h>

#include <fcntl.h>
#include <stdlib.h>
#include <sys/mount.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <sys/sysmacros.h>
#include <sys/wait.h>

using android::base::StringPrintf;
using android::base::unique_fd;

namespace android {
namespace vold {

ObbVolume::ObbVolume(int id, const std::string& sourcePath, const std::string& sourceKey,
        gid_t ownerGid) : VolumeBase(Type::kObb) {
    setId(StringPrintf("obb:%d", id));
    mSourcePath = sourcePath;
    mSourceKey = sourceKey;
    mOwnerGid = ownerGid;
}

ObbVolume::~ObbVolume() {
}

status_t ObbVolume::doCreate() {
    if (Loop::create(mSourcePath, mLoopPath)) {
        PLOG(ERROR) << getId() << " failed to create loop";
        return -1;
    }

    if (!mSourceKey.empty()) {
        unsigned long nr_sec = 0;
        {
            unique_fd loop_fd(open(mLoopPath.c_str(), O_RDWR | O_CLOEXEC));
            if (loop_fd.get() == -1) {
                PLOG(ERROR) << getId() << " failed to open loop";
                return -1;
            }

            get_blkdev_size(loop_fd.get(), &nr_sec);
            if (nr_sec == 0) {
                PLOG(ERROR) << getId() << " failed to get loop size";
                return -1;
            }
        }

        char tmp[PATH_MAX];
        if (Devmapper::create(getId().c_str(), mLoopPath.c_str(), mSourceKey.c_str(), nr_sec,
                tmp, PATH_MAX)) {
            PLOG(ERROR) << getId() << " failed to create dm";
            return -1;
        }
        mDmPath = tmp;
        mMountPath = mDmPath;
    } else {
        mMountPath = mLoopPath;
    }
    return OK;
}

status_t ObbVolume::doDestroy() {
    if (!mDmPath.empty() && Devmapper::destroy(getId().c_str())) {
        PLOG(WARNING) << getId() << " failed to destroy dm";
    }
    if (!mLoopPath.empty() && Loop::destroyByDevice(mLoopPath.c_str())) {
        PLOG(WARNING) << getId() << " failed to destroy loop";
    }
    mDmPath.clear();
    mLoopPath.clear();
    return OK;
}

status_t ObbVolume::doMount() {
    auto path = StringPrintf("/mnt/obb/%s", getId().c_str());
    setPath(path);

    if (fs_prepare_dir(path.c_str(), 0700, AID_ROOT, AID_ROOT)) {
        PLOG(ERROR) << getId() << " failed to create mount point";
        return -1;
    }
    if (android::vold::vfat::Mount(mMountPath, path,
            true, false, true, 0, mOwnerGid, 0227, false)) {
        PLOG(ERROR) << getId() << " failed to mount";
        return -1;
    }
    return OK;
}

status_t ObbVolume::doUnmount() {
    auto path = getPath();

    KillProcessesUsingPath(path);
    ForceUnmount(path);
    rmdir(path.c_str());

    return OK;
}

}  // namespace vold
}  // namespace android
