/**
 * Get encryption status for an Android user
 *
 * @param user Android user id
 *
 * @return Encryption status(encrypted/unecrypted/in progress) or negative value in case of an error
 */
int android_get_encrypted_user_status(int user)
{
    int ret, data_storage_status, media_storage_status;
    char storage_path[MAX_PATH_LENGTH], private_dir_path[MAX_PATH_LENGTH];

    memset(storage_path, 0, sizeof(storage_path));
    sprintf(storage_path, "%s%d/", ANDROID_USER_DATA_PATH, user);
    ret = get_private_storage_path(private_dir_path, storage_path);
    if (ret < 0) {
        LOGE("Error getting private storage for %s", storage_path);
        return ret;
    }

    ret = access(private_dir_path, F_OK);
    if (ret < 0) {
        LOGI("User %d not encrypted", user);
        return ret;
    }

    data_storage_status = EFS_get_status(storage_path);
    if (data_storage_status < 0) {
        LOGE("Unable to get status for %s.%d", ANDROID_USER_DATA_PATH,
             user);
        return ret;
    }

    memset(storage_path, 0, sizeof(storage_path));
    sprintf(storage_path, "%s%d/", ANDROID_VIRTUAL_SDCARD_PATH, user);

    ret = get_private_storage_path(private_dir_path, storage_path);
    if (ret < 0) {
        LOGE("Error getting private storage for %s", storage_path);
        return ret;
    }

    ret = access(private_dir_path, F_OK);
    if (ret < 0) {
        LOGE("Private storage %s does not exist for media",
             private_dir_path);
        return ret;
    }

    media_storage_status = EFS_get_status(storage_path);
    if (media_storage_status < 0) {
        LOGE("Unable to get status for %s.%d", ANDROID_USER_DATA_PATH,
             user);
        return ret;
    }

    if (media_storage_status != data_storage_status) {
        LOGE("Inconsistent encryption status for user %d", user);
        return -1;
    }

    LOGI("Encryption status for user %d is %d", user, data_storage_status);
    return data_storage_status;
}
int EncryptedFileStorageCmd::runCommand(SocketClient *cli, int argc, char **argv) {
    int rc = 0;

    if ((cli->getUid() != 0) && (cli->getUid() != AID_SYSTEM)) {
        cli->sendMsg(ResponseCode::CommandNoPermission, "No permission to run EFS commands", false);
        return 0;
    }

    if (argc < 3) {
        cli->sendMsg(ResponseCode::CommandSyntaxError, "Missing Argument", false);
        return 0;
    }

    if (!strcmp(argv[1], "create")) {
        if (argc != 4) {
            cli->sendMsg(ResponseCode::CommandSyntaxError, "Usage: efs create <storage_path> <passwd>", false);
            return 0;
        }
        rc = EFS_create(argv[2],argv[3]);
    } else if (!strcmp(argv[1], "unlock")) {
        if (argc != 4) {
            cli->sendMsg(ResponseCode::CommandSyntaxError, "Usage: efs unlock <storage_path> <passwd>", false);
            return 0;
        }
        rc = EFS_unlock(argv[2], argv[3]);
    } else if (!strcmp(argv[1], "lock")) {
        if (argc != 3) {
            cli->sendMsg(ResponseCode::CommandSyntaxError, "Usage: efs lock <storage_path>", false);
            return 0;
        }
        rc = EFS_lock(argv[2]);
    } else if (!strcmp(argv[1], "change_passwd")) {
        if (argc != 5) {
            cli->sendMsg(ResponseCode::CommandSyntaxError, "Usage: efs change_passwd <storage_path> <old_passwd> <new_passwd>", false);
            return 0;
        }
        rc = EFS_change_password(argv[2],argv[3],argv[4]);
    } else if (!strcmp(argv[1], "remove")) {
        if (argc != 3) {
            cli->sendMsg(ResponseCode::CommandSyntaxError, "Usage: efs remove <storage_path>", false);
            return 0;
        }
        rc = EFS_remove(argv[2]);
    } else if (!strcmp(argv[1], "recover")) {
        if (argc != 4) {
            cli->sendMsg(ResponseCode::CommandSyntaxError, "Usage: efs recover <storage_path> <password>", false);
            return 0;
        }
        rc = EFS_recover_data_and_remove(argv[2], argv[3]);
    } else if (!strcmp(argv[1], "stat")) {
        if (argc != 3) {
            cli->sendMsg(ResponseCode::CommandSyntaxError, "Usage: efs stat <storage_path>", false);
            return 0;
        }
        rc = EFS_get_status(argv[2]);
    } else if (!strcmp(argv[1], "get_progress")) {
		if (argc != 3) {
            cli->sendMsg(ResponseCode::CommandSyntaxError, "Usage: efs get_progress <storage_path>", false);
            return 0;
		}
		rc = EFS_get_progress(argv[2]);
	} else if (!strcmp(argv[1], "encrypt_user_data")) {
        if (argc != 4) {
            cli->sendMsg(ResponseCode::CommandSyntaxError, "Usage: efs encrypt_user_data <userId> <password>", false);
            return 0;
        }
        rc = android_encrypt_user_data(atoi(argv[2]), argv[3]);
    } else if (!strcmp(argv[1], "unlock_user_data")) {
        if (argc != 4) {
            cli->sendMsg(ResponseCode::CommandSyntaxError, "Usage: efs unlock_user_data <userId> <password>", false);
            return 0;
        }
        rc = android_unlock_user_data(atoi(argv[2]), argv[3]);
    }  else if (!strcmp(argv[1], "lock_user_data")) {
        if (argc != 3) {
            cli->sendMsg(ResponseCode::CommandSyntaxError, "Usage: efs lock_user_data <userId>", false);
            return 0;
        }
        rc = android_lock_user_data(atoi(argv[2]));
    } else if (!strcmp(argv[1], "change_user_data_passwd")) {
        if (argc != 5) {
            cli->sendMsg(ResponseCode::CommandSyntaxError, "Usage: efs change_user_data_passwd <userId> <old_passwd> <new_passwd>", false);
            return 0;
        }
        rc = android_change_user_data_password(atoi(argv[2]),argv[3],argv[4]);
    } else if (!strcmp(argv[1], "decrypt_user_data")) {
        if (argc != 4) {
            cli->sendMsg(ResponseCode::CommandSyntaxError, "Usage: efs decrypt_user_data <userId> <password>", false);
            return 0;
        }
        rc = android_decrypt_user_data(atoi(argv[2]), argv[3]);
    }  else if (!strcmp(argv[1], "remove_user_encrypted_data")) {
        if (argc != 3) {
            cli->sendMsg(ResponseCode::CommandSyntaxError, "Usage: efs remove_user_encrypted_data <userId>", false);
            return 0;
        }
        rc = android_remove_user_encrypted_data(atoi(argv[2]));
    }   else if (!strcmp(argv[1], "user_stat")) {
        if (argc != 3) {
            cli->sendMsg(ResponseCode::CommandSyntaxError, "Usage: efs user_stat <userId>", false);
            return 0;
        }
        rc = android_get_encrypted_user_status(atoi(argv[2]));
    }
    else {
        cli->sendMsg(ResponseCode::CommandSyntaxError, "Unknown efs-tools cmd", false);
    }

    // Always report that the command succeeded and return the error code.
    // The caller will check the return value to see what the error was.
    char msg[255];
    snprintf(msg, sizeof(msg), "%d", rc);
    cli->sendMsg(ResponseCode::CommandOkay, msg, false);

    return 0;
}