/*
 * Copyright (C) 2008 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 <stdlib.h>
#include <string.h>
#include <dirent.h>
#include <errno.h>
#include <fcntl.h>

#include <sys/types.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <sys/mman.h>
#include <sys/mount.h>

#include <linux/kdev_t.h>

#include <cutils/properties.h>

#include "diskmbr.h"

#define LOG_TAG "Vold"

#include <cutils/log.h>

#include "Volume.h"
#include "VolumeManager.h"
#include "ResponseCode.h"
#include "Fat.h"

extern "C" void KillProcessesWithOpenFiles(const char *, int, int, int);
extern "C" void dos_partition_dec(void const *pp, struct dos_partition *d);
extern "C" void dos_partition_enc(void *pp, struct dos_partition *d);

static const char *stateToStr(int state) {
    if (state == Volume::State_Init)
        return "Initializing";
    else if (state == Volume::State_NoMedia)
        return "No-Media";
    else if (state == Volume::State_Idle)
        return "Idle-Unmounted";
    else if (state == Volume::State_Pending)
        return "Pending";
    else if (state == Volume::State_Mounted)
        return "Mounted";
    else if (state == Volume::State_Unmounting)
        return "Unmounting";
    else if (state == Volume::State_Checking)
        return "Checking";
    else if (state == Volume::State_Formatting)
        return "Formatting";
    else if (state == Volume::State_Shared)
        return "Shared-Unmounted";
    else if (state == Volume::State_SharedMnt)
        return "Shared-Mounted";
    else
        return "Unknown-Error";
}

Volume::Volume(VolumeManager *vm, const char *label, const char *mount_point) {
    mVm = vm;
    mLabel = strdup(label);
    mMountpoint = strdup(mount_point);
    mState = Volume::State_Init;
    mCurrentlyMountedKdev = -1;
}

Volume::~Volume() {
    free(mLabel);
    free(mMountpoint);
}

dev_t Volume::getDiskDevice() {
    return MKDEV(0, 0);
};

void Volume::handleVolumeShared() {
}

void Volume::handleVolumeUnshared() {
}

int Volume::handleBlockEvent(NetlinkEvent *evt) {
    errno = ENOSYS;
    return -1;
}

void Volume::setState(int state) {
    char msg[255];
    int oldState = mState;

    if (oldState == state) {
        LOGW("Duplicate state (%d)\n", state);
        return;
    }

    mState = state;

    LOGD("Volume %s state changing %d (%s) -> %d (%s)", mLabel,
         oldState, stateToStr(oldState), mState, stateToStr(mState));
    snprintf(msg, sizeof(msg),
             "Volume %s %s state changed from %d (%s) to %d (%s)", getLabel(),
             getMountpoint(), oldState, stateToStr(oldState), mState,
             stateToStr(mState));

    mVm->getBroadcaster()->sendBroadcast(ResponseCode::VolumeStateChange,
                                         msg, false);
}

int Volume::createDeviceNode(const char *path, int major, int minor) {
    mode_t mode = 0660 | S_IFBLK;
    dev_t dev = (major << 8) | minor;
    if (mknod(path, mode, dev) < 0) {
        if (errno != EEXIST) {
            return -1;
        }
    }
    return 0;
}

int Volume::formatVol() {

    if (getState() == Volume::State_NoMedia) {
        errno = ENODEV;
        return -1;
    } else if (getState() != Volume::State_Idle) {
        errno = EBUSY;
        return -1;
    }

    if (isMountpointMounted(getMountpoint())) {
        LOGW("Volume is idle but appears to be mounted - fixing");
        setState(Volume::State_Mounted);
        // mCurrentlyMountedKdev = XXX
        errno = EBUSY;
        return -1;
    }

    char devicePath[255];
    dev_t diskNode = getDiskDevice();
    dev_t partNode = MKDEV(MAJOR(diskNode), 1); // XXX: Hmmm

    sprintf(devicePath, "/dev/block/vold/%d:%d",
            MAJOR(diskNode), MINOR(diskNode));

    LOGI("Volume %s (%s) MBR being initialized", getLabel(), devicePath);

    if (initializeMbr(devicePath)) {
        LOGE("Failed to initialize MBR (%s)", strerror(errno));
        goto err;
    }

    sprintf(devicePath, "/dev/block/vold/%d:%d",
            MAJOR(partNode), MINOR(partNode));

    LOGI("Volume %s (%s) being formatted", getLabel(), devicePath);

    if (Fat::format(devicePath)) {
        LOGE("Failed to format (%s)", strerror(errno));
        goto err;
    }

    LOGI("Volume %s (%s) formatted sucessfully", getLabel(), devicePath);
    return 0;
err:
    return -1;
}

bool Volume::isMountpointMounted(const char *path) {
    char device[256];
    char mount_path[256];
    char rest[256];
    FILE *fp;
    char line[1024];

    if (!(fp = fopen("/proc/mounts", "r"))) {
        LOGE("Error opening /proc/mounts (%s)", strerror(errno));
        return false;
    }

    while(fgets(line, sizeof(line), fp)) {
        line[strlen(line)-1] = '\0';
        sscanf(line, "%255s %255s %255s\n", device, mount_path, rest);
        if (!strcmp(mount_path, path)) {
            fclose(fp);
            return true;
        }

    }

    fclose(fp);
    return false;
}

int Volume::mountVol() {
    dev_t deviceNodes[4];
    int n, i, rc = 0;
    char errmsg[255];

    if (getState() == Volume::State_NoMedia) {
        snprintf(errmsg, sizeof(errmsg),
                 "Volume %s %s mount failed - no media",
                 getLabel(), getMountpoint());
        mVm->getBroadcaster()->sendBroadcast(
                                         ResponseCode::VolumeMountFailedNoMedia,
                                         errmsg, false);
        errno = ENODEV;
        return -1;
    } else if (getState() != Volume::State_Idle) {
        errno = EBUSY;
        return -1;
    }

    if (isMountpointMounted(getMountpoint())) {
        LOGW("Volume is idle but appears to be mounted - fixing");
        setState(Volume::State_Mounted);
        // mCurrentlyMountedKdev = XXX
        return 0;
    }

    n = getDeviceNodes((dev_t *) &deviceNodes, 4);
    if (!n) {
        LOGE("Failed to get device nodes (%s)\n", strerror(errno));
        return -1;
    }

    for (i = 0; i < n; i++) {
        char devicePath[255];

        sprintf(devicePath, "/dev/block/vold/%d:%d", MAJOR(deviceNodes[i]),
                MINOR(deviceNodes[i]));

        LOGI("%s being considered for volume %s\n", devicePath, getLabel());

        errno = 0;
        setState(Volume::State_Checking);

        if ((rc = Fat::check(devicePath))) {
            if (errno == ENODATA) {
                LOGW("%s does not contain a FAT filesystem\n", devicePath);
                continue;
            }
            errno = EIO;
            /* Badness - abort the mount */
            LOGE("%s failed FS checks (%s)", devicePath, strerror(errno));
            setState(Volume::State_Idle);
            return -1;
        }

        LOGI("%s checks out - attempting to mount\n", devicePath);
        errno = 0;
        if (!(rc = Fat::doMount(devicePath, getMountpoint(), false, false,
                                1000, 1015, 0702, true))) {
            LOGI("%s sucessfully mounted for volume %s\n", devicePath, getLabel());
            setState(Volume::State_Mounted);
            mCurrentlyMountedKdev = deviceNodes[i];
            return 0;
        }

        LOGW("%s failed to mount via VFAT (%s)\n", devicePath, strerror(errno));
    }

    LOGE("Volume %s found no suitable devices for mounting :(\n", getLabel());
    setState(Volume::State_Idle);

    return -1;
}

int Volume::unmountVol() {
    int i, rc;

    if (getState() != Volume::State_Mounted) {
        LOGE("Volume %s unmount request when not mounted", getLabel());
        errno = EINVAL;
        return -1;
    }

    setState(Volume::State_Unmounting);
    for (i = 0; i < 10; i++) {
        rc = umount(getMountpoint());
        if (!rc)
            break;

        if (rc && (errno == EINVAL || errno == ENOENT)) {
            rc = 0;
            break;
        }

        LOGW("Volume %s unmount attempt %d failed (%s)",
             getLabel(), i + 1, strerror(errno));

        if (i < 5) {
            usleep(1000 * 250);
        } else {
            KillProcessesWithOpenFiles(getMountpoint(),
                                       (i < 7 ? 0 : 1),
                                       NULL, 0);
            usleep(1000 * 250);
        }
    }

    if (!rc) {
        LOGI("Volume %s unmounted sucessfully", getLabel());
        setState(Volume::State_Idle);
        mCurrentlyMountedKdev = -1;
        return 0;
    }

    LOGE("Volume %s failed to unmount (%s)\n", getLabel(), strerror(errno));
    setState(Volume::State_Mounted);
    return -1;
}

int Volume::initializeMbr(const char *deviceNode) {
    int fd, rc;
    unsigned char block[512];
    struct dos_partition part;
    unsigned int nr_sec;

    if ((fd = open(deviceNode, O_RDWR)) < 0) {
        LOGE("Error opening disk file (%s)", strerror(errno));
        return -1;
    }

    if (ioctl(fd, BLKGETSIZE, &nr_sec)) {
        LOGE("Unable to get device size (%s)", strerror(errno));
        close(fd);
        return -1;
    }

    memset(&part, 0, sizeof(part));
    part.dp_flag = 0x80;
    part.dp_typ = 0xc;
    part.dp_start = ((1024 * 64) / 512) + 1;
    part.dp_size = nr_sec - part.dp_start;

    memset(block, 0, sizeof(block));
    block[0x1fe] = 0x55;
    block[0x1ff] = 0xaa;

    dos_partition_enc(block + DOSPARTOFF, &part);

    if (write(fd, block, sizeof(block)) < 0) {
        LOGE("Error writing MBR (%s)", strerror(errno));
        close(fd);
        return -1;
    }

    if (ioctl(fd, BLKRRPART, NULL) < 0) {
        LOGE("Error re-reading partition table (%s)", strerror(errno));
        close(fd);
        return -1;
    }
    close(fd);
    return 0;
}
