/* Copyright (C) 2012 The Android Open Source Project
**
** This software is licensed under the terms of the GNU General Public
** License version 2, as published by the Free Software Foundation, and
** may be copied, distributed, and modified under those terms.
**
** This program is distributed in the hope that it will be useful,
** but WITHOUT ANY WARRANTY; without even the implied warranty of
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
** GNU General Public License for more details.
*/

#include "qemu-common.h"
#include "android/globals.h"
#include "android/snaphost-android.h"
#include "android/utils/debug.h"

#define  E(...)    derror(__VA_ARGS__)
#define  W(...)    dwarning(__VA_ARGS__)
#define  D(...)    VERBOSE_PRINT(init,__VA_ARGS__)

/* Compares two instance of an ini file.
 * This routine compares all entries (key,value pairs) found in one ini file
 * against entries in another file. The files are considered to be equal if:
 * 1. Number of entries in each file is equal.
 * 2. Each entry in one file has a corresponded entry in another file, and their
 *    values are equal.
 * Param:
 *  current - Ini file containing the current configuration.
 *  saved - Ini file containing a previously saved configuration.
 * Return:
 *  0 if files are equal, or 1 if they are not equal, or -1 if an error has
 * occurred.
 */
static int
_cmp_hw_config(IniFile* current, IniFile* saved)
{
    int n, ret = 0;
    const int num_pairs = iniFile_getPairCount(current);

    /* Check 1: must contain same number of entries. */
    if (num_pairs != iniFile_getPairCount(saved)) {
        D("Different numbers of entries in the HW config files. Current contains %d, while saved contains %d entries.",
          num_pairs, iniFile_getPairCount(saved));
        return -1;
    }

    /* Iterate through the entries in the current file, comparing them to entries
     * in the saved file. */
    for (n = 0; n < num_pairs && ret == 0; n++) {
        char* key, *value1, *value2;

        if (iniFile_getEntry(current, n, &key, &value1)) {
            D("Unable to obtain entry %d from the current HW config file", n);
            return -1;
        }

        value2 = iniFile_getString(saved, key, "");
        if (value2 == NULL) {
            D("Saved HW config file is missing entry ('%s', '%s') found in the current HW config.",
              key, value1);
            free(key);
            free(value1);
            return 1;
        }

        ret = strcmp(value1, value2);
        if (ret) {
            D("HW config value mismatch for a key '%s': current is '%s' while saved was '%s'",
              key, value1, value2);
        }

        free(value2);
        free(value1);
        free(key);
    }

    return ret ? 1 : 0;
}

/* Builds path to the HW config backup file that is used to store HW config
 * settings used for that snapshot. The backup path is a concatenation of the
 * snapshot storage file path, snapshot name, and an 'ini' extension. This
 * way we can track HW configuration for different snapshot names store in
 * different storage files.
 * Param:
 *  name - Name of the snapshot inside the snapshot storage file.
 * Return:
 *  Path to the HW config backup file on success, or NULL on an error.
 */
static char*
_build_hwcfg_path(const char* name)
{
    const int path_len = strlen(android_hw->disk_snapStorage_path) +
                         strlen(name) + 6;
    char* bkp_path = malloc(path_len);
    if (bkp_path == NULL) {
        E("Unable to allocate %d bytes for HW config path!", path_len);
        return NULL;
    }

    snprintf(bkp_path, path_len, "%s.%s.ini",
             android_hw->disk_snapStorage_path, name);

    return bkp_path;
}

int
snaphost_match_configs(IniFile* hw_ini, const char* name)
{
    /* Make sure that snapshot storage path is valid. */
    if (android_hw->disk_snapStorage_path == NULL ||
        *android_hw->disk_snapStorage_path == '\0') {
        return 1;
    }

    /* Build path to the HW config for the loading VM. */
    char* bkp_path = _build_hwcfg_path(name);
    if (bkp_path == NULL) {
        return 0;
    }

    /* Load HW config from the previous emulator launch. */
    IniFile* hwcfg_bkp = iniFile_newFromFile(bkp_path);

    if (hwcfg_bkp != NULL) {
        if (_cmp_hw_config(hw_ini, hwcfg_bkp)) {
            E("Unable to load VM from snapshot. The snapshot has been saved for a different hardware configuration.");
            free(bkp_path);
            return 0;
        }
        iniFile_free(hwcfg_bkp);
    } else {
        /* It could be that a snapshot file has been copied from another
         * location without copying the backup file, or snapshot file has not
         * been created yet. In either case we can't do much checking here,
         * so, lets be hopefull that user knows what (s)he is doing. */
        D("Missing HW config backup file '%s'", bkp_path);
    }

    free(bkp_path);

    return 1;
}

void
snaphost_save_config(const char* name)
{
    /* Make sure that snapshot storage path is valid. */
    if (android_hw->disk_snapStorage_path == NULL ||
        *android_hw->disk_snapStorage_path == '\0') {
        return;
    }

    /* Build path to the HW config for the saving VM. */
    char* bkp_path = _build_hwcfg_path(name);
    if (bkp_path == NULL) {
        return;
    }

    /* Create HW config backup file from the current HW config settings. */
    IniFile* hwcfg_bkp = iniFile_newFromMemory("", bkp_path);
    if (hwcfg_bkp == NULL) {
        W("Unable to create backup HW config file '%s'. Error: %s",
          bkp_path, strerror(errno));
        return;
    }
    androidHwConfig_write(android_hw, hwcfg_bkp);

    /* Invalidate data partition initialization path in the backup copy of HW
     * config. The reason we need to do this is that we want the system loading
     * from the snapshot to be in sync with the data partition the snapshot was
     * saved for. For that we must disalow overwritting it on snapshot load. In
     * other words, we should allow snapshot loading only on condition
     * that disk.dataPartition.initPath is empty. */
    iniFile_setValue(hwcfg_bkp, "disk.dataPartition.initPath", "");

    /* Save backup file. */
    if (!iniFile_saveToFileClean(hwcfg_bkp, bkp_path)) {
        D("HW config has been backed up to '%s'", bkp_path);
    } else {
        /* Treat this as a "soft" error. Yes, we couldn't save the backup, but
         * this should not cancel snapshot saving. */
        W("Unable to save HW config file '%s'. Error: %s", bkp_path, strerror(errno));
    }
    iniFile_free(hwcfg_bkp);
    free(bkp_path);
}
