/*
 * Copyright (C) 2015 The Android Open Source Project
 * Copyright (C) 2019 The LineageOS 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 "PublicVolume.h"
#include <volume_manager/ResponseCode.h>
#include <volume_manager/VolumeManager.h>
#include "Utils.h"
#include "fs/Exfat.h"
#include "fs/Ext4.h"
#include "fs/F2fs.h"
#include "fs/Ntfs.h"
#include "fs/Vfat.h"

#include <android-base/logging.h>
#include <android-base/stringprintf.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/sysmacros.h>
#include <sys/types.h>
#include <sys/wait.h>

using android::base::StringPrintf;

namespace android {
namespace volmgr {

PublicVolume::PublicVolume(dev_t device, const std::string& nickname,
                           const std::string& fstype /* = "" */,
                           const std::string& mntopts /* = "" */)
    : VolumeBase(Type::kPublic), mDevice(device), mFsType(fstype), mMntOpts(mntopts) {
    setId(StringPrintf("public:%u_%u", major(device), minor(device)));
    setPartLabel(nickname);
    mDevPath = StringPrintf("/dev/block/volmgr/%s", getId().c_str());
}

PublicVolume::~PublicVolume() {}

status_t PublicVolume::readMetadata() {
    std::string label;
    status_t res = ReadMetadataUntrusted(mDevPath, mFsType, mFsUuid, label);
    if (!label.empty()) {
        setPartLabel(label);
    }
    VolumeManager::Instance()->notifyEvent(ResponseCode::VolumeFsTypeChanged, mFsType);
    VolumeManager::Instance()->notifyEvent(ResponseCode::VolumeFsUuidChanged, mFsUuid);
    return res;
}

status_t PublicVolume::doCreate() {
    status_t res = CreateDeviceNode(mDevPath, mDevice);
    if (res != OK) {
        return res;
    }
    readMetadata();

    // Use UUID as stable name, if available
    std::string stableName = getId();
    if (!mFsUuid.empty()) {
        stableName = mFsUuid;
    }
    setPath(StringPrintf("/storage/%s", stableName.c_str()));

    return OK;
}

status_t PublicVolume::doDestroy() {
    return DestroyDeviceNode(mDevPath);
}

status_t PublicVolume::doMount() {
    if (!IsFilesystemSupported(mFsType)) {
        LOG(ERROR) << getId() << " unsupported filesystem " << mFsType;
        return -EIO;
    }

    if (fs_prepare_dir(getPath().c_str(), 0700, AID_ROOT, AID_ROOT)) {
        PLOG(ERROR) << getId() << " failed to create mount points";
        return -errno;
    }

    int ret = 0;
    if (mFsType == "exfat") {
        ret = exfat::Mount(mDevPath, getPath(), AID_MEDIA_RW, AID_MEDIA_RW, 0007);
    } else if (mFsType == "ext4") {
        ret = ext4::Mount(mDevPath, getPath(), false, false, true, mMntOpts, false, true);
    } else if (mFsType == "f2fs") {
        ret = f2fs::Mount(mDevPath, getPath(), mMntOpts, false, true);
    } else if (mFsType == "ntfs") {
        ret =
            ntfs::Mount(mDevPath, getPath(), false, false, false, AID_MEDIA_RW, AID_MEDIA_RW, 0007);
    } else if (mFsType == "vfat") {
        ret = vfat::Mount(mDevPath, getPath(), false, false, false, AID_MEDIA_RW, AID_MEDIA_RW,
                          0007, true);
    } else {
        ret = ::mount(mDevPath.c_str(), getPath().c_str(), mFsType.c_str(), 0, nullptr);
    }
    if (ret) {
        PLOG(ERROR) << getId() << " failed to mount " << mDevPath;
        return -EIO;
    }

    return OK;
}

status_t PublicVolume::doUnmount(bool detach /* = false */) {
    ForceUnmount(getPath(), detach);

    rmdir(getPath().c_str());

    return OK;
}

}  // namespace volmgr
}  // namespace android
