/* 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 "android/snaphost-android.h"

#include "android/globals.h"
#include "android/utils/debug.h"

#include <errno.h>
#include <stdlib.h>
#include <string.h>
#include <stdio.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(CIniFile* current, CIniFile* saved) {
    int n, ret = 0;
    const int num_pairs = iniFile_getPairCount(current);

    /* Check 1: better contain same number of entries; but this is a non-fatal requirement*/
    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(CIniFile* 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. */
    CIniFile* hwcfg_bkp = iniFile_newFromFile(bkp_path);

    if (hwcfg_bkp != NULL && iniFile_getPairCount(hwcfg_bkp) > 0) {
        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. */
    CIniFile* hwcfg_bkp = iniFile_newEmpty(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);
}
