/*
 * Copyright (C) 2009 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 <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/mount.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>

#include "efs_migration.h"
#include "cutils/misc.h"
#include "cutils/properties.h"
#include "common.h"
#include "mtdutils/mtdutils.h"
#include "mtdutils/mounts.h"
#include "roots.h"

const char* efs_enabled_property = "persist.security.efs.enabled";
const char* efs_transition_property = "persist.security.efs.trans";
const char* efs_property_dir = "/data/property/";

void get_property_file_name(char *buffer, const char *property_name) {
    sprintf(buffer, "%s%s", efs_property_dir, property_name);
}

int get_text_file_contents(char *buffer, int buf_size, char *file_name) {
    FILE *in_file;
    char *read_data;

    in_file = fopen(file_name, "r");
    if (in_file == NULL) {
        LOGE("Encrypted FS: error accessing properties.");
        return EFS_ERROR;
    }

    read_data = fgets(buffer, buf_size, in_file);
    if (read_data == NULL) {
        // Error or unexpected data
        fclose(in_file);
        LOGE("Encrypted FS: error accessing properties.");
        return EFS_ERROR;
    }

    fclose(in_file);
    return EFS_OK;
}

int set_text_file_contents(char *buffer, char *file_name) {
    FILE *out_file;
    int result;

    out_file = fopen(file_name, "w");
    if (out_file == NULL) {
        LOGE("Encrypted FS: error setting up properties.");
        return EFS_ERROR;
    }

    result = fputs(buffer, out_file);
    if (result != 0) {
        // Error or unexpected data
        fclose(out_file);
        LOGE("Encrypted FS: error setting up properties.");
        return EFS_ERROR;
    }

    fflush(out_file);
    fclose(out_file);
    return EFS_OK;
}


int read_efs_boolean_property(const char *prop_name, int *value) {
    char prop_file_name[PROPERTY_KEY_MAX + 32];
    char prop_value[PROPERTY_VALUE_MAX];
    int result;

    get_property_file_name(prop_file_name, prop_name);
    result = get_text_file_contents(prop_value, PROPERTY_VALUE_MAX, prop_file_name);

    if (result < 0) {
        return result;
    }

    if (strncmp(prop_value, "1", 1) == 0) {
        *value = 1;
    } else if (strncmp(prop_value, "0", 1) == 0) {
        *value = 0;
    } else {
        LOGE("Encrypted FS: error accessing properties.");
        return EFS_ERROR;
    }

    return EFS_OK;
}

int write_efs_boolean_property(const char *prop_name, int value) {
    char prop_file_name[PROPERTY_KEY_MAX + 32];
    char prop_value[PROPERTY_VALUE_MAX];
    int result;

    get_property_file_name(prop_file_name, prop_name);

    // Create the directory if needed
    mkdir(efs_property_dir, 0755);
    if (value == 1) {
        result = set_text_file_contents("1", prop_file_name);
    } else if (value == 0) {
        result = set_text_file_contents("0", prop_file_name);
    } else {
        return EFS_ERROR;
    }
    if (result < 0) {
        return result;
    }

    return EFS_OK;
}

int read_encrypted_fs_info(encrypted_fs_info *efs_data) {
    int result;
    int value;
    result = ensure_root_path_mounted("DATA:");
    if (result != 0) {
        LOGE("Encrypted FS: error mounting userdata partition.");
        return EFS_ERROR;
    }

    // STOPSHIP: Read the EFS key from a file (TBD later)
    // Future code goes here...

    result = ensure_root_path_unmounted("DATA:");
    if (result != 0) {
        LOGE("Encrypted FS: error unmounting data partition.");
        return EFS_ERROR;
    }

    return EFS_OK;
}

int restore_encrypted_fs_info(encrypted_fs_info *efs_data) {
    int result;
    result = ensure_root_path_mounted("DATA:");
    if (result != 0) {
        LOGE("Encrypted FS: error mounting userdata partition.");
        return EFS_ERROR;
    }

    // Set the EFS properties to their respective values
    result = write_efs_boolean_property(efs_enabled_property, efs_data->encrypted_fs_mode);
    if (result != 0) {
        return result;
    }

    // Signal "transition" of Encrypted File System settings
    result = write_efs_boolean_property(efs_transition_property, 1);
    if (result != 0) {
        return result;
    }

    result = ensure_root_path_unmounted("DATA:");
    if (result != 0) {
        LOGE("Encrypted FS: error unmounting data partition.");
        return EFS_ERROR;
    }

    return EFS_OK;
}

