/*
 * plistutil.c
 * Simple tool to convert a plist into different formats
 *
 * Copyright (c) 2009-2015 Martin Szulecki All Rights Reserved.
 * Copyright (c) 2008 Zach C. All Rights Reserved.
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library 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
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
 */


#include "plist/plist.h"

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/stat.h>
#include <errno.h>
#include <unistd.h>

#define BUF_SIZE 2048 // Seems to be a decent start to cover most stdin files

#ifdef _MSC_VER
#pragma warning(disable:4996)
#endif

typedef struct _options
{
    char *in_file, *out_file;
    uint8_t debug, in_fmt, out_fmt; // fmts 0 = undef, 1 = bin, 2 = xml, 3 = json someday
} options_t;

static void print_usage(int argc, char *argv[])
{
    char *name = NULL;
    name = strrchr(argv[0], '/');
    printf("Usage: %s -i|--infile FILE [-o|--outfile FILE] [-d|--debug]\n", (name ? name + 1: argv[0]));
    printf("Convert a plist FILE from binary to XML format or vice-versa.\n\n");
    printf("  -i, --infile FILE    Optional FILE to convert from or stdin if - or not used\n");
    printf("  -o, --outfile FILE   Optional FILE to convert to or stdout if - or not used\n");
    printf("  -f, --format [bin|xml]  Force output format, regardless of input type\n");
    printf("  -d, --debug          Enable extended debug output\n");
    printf("\n");
}

static options_t *parse_arguments(int argc, char *argv[])
{
    int i = 0;

    options_t *options = (options_t *) malloc(sizeof(options_t));
    memset(options, 0, sizeof(options_t));
    options->out_fmt = 0;

    for (i = 1; i < argc; i++)
    {
        if (!strcmp(argv[i], "--infile") || !strcmp(argv[i], "-i"))
        {
            if ((i + 1) == argc)
            {
                free(options);
                return NULL;
            }
            options->in_file = argv[i + 1];
            i++;
            continue;
        }

        if (!strcmp(argv[i], "--outfile") || !strcmp(argv[i], "-o"))
        {
            if ((i + 1) == argc)
            {
                free(options);
                return NULL;
            }
            options->out_file = argv[i + 1];
            i++;
            continue;
        }

        if (!strcmp(argv[i], "--format") || !strcmp(argv[i], "-f"))
        {
            if ((i + 1) == argc)
            {
                free(options);
                return NULL;
            }
            if (!strncmp(argv[i+1], "bin", 3)) {
                options->out_fmt = 1;
            } else if (!strncmp(argv[i+1], "xml", 3)) {
                options->out_fmt = 2;
            } else {
                printf("ERROR: Unsupported output format\n");
                free(options);
                return NULL;
            }
            i++;
            continue;
        }

        if (!strcmp(argv[i], "--debug") || !strcmp(argv[i], "-d"))
        {
            options->debug = 1;
        }

        if (!strcmp(argv[i], "--help") || !strcmp(argv[i], "-h"))
        {
            free(options);
            return NULL;
        }
    }

    return options;
}

int main(int argc, char *argv[])
{
    FILE *iplist = NULL;
    plist_t root_node = NULL;
    char *plist_out = NULL;
    uint32_t size = 0;
    int read_size = 0;
    char *plist_entire = NULL;
    struct stat filestats;
    options_t *options = parse_arguments(argc, argv);

    if (!options)
    {
        print_usage(argc, argv);
        return 0;
    }

    if (!options->in_file || !strcmp(options->in_file, "-"))
    {
	read_size = 0;
        plist_entire = malloc(sizeof(char) * BUF_SIZE);
        if(plist_entire == NULL)
        {
            printf("ERROR: Failed to allocate buffer to read from stdin");
	    free(options);
            return 1;
        }
	plist_entire[read_size] = '\0';
        char ch;
	while(read(STDIN_FILENO, &ch, 1) > 0)
        {
            if (read_size >= BUF_SIZE) {
                char *old = plist_entire;
                plist_entire = realloc(plist_entire, sizeof(char) * (read_size + 1));
                if (plist_entire == NULL)
                {
                    printf("ERROR: Failed to reallocate stdin buffer\n");
                    free(old);
                    free(options);
                    return 1;
                }
            }
            plist_entire[read_size] = ch;
            read_size++;
        }
        plist_entire[read_size] = '\0';

	// Not positive we need this, but it doesnt seem to hurt lol
        if(ferror(stdin))
        {
            printf("ERROR: reading from stdin.\n");
            free(plist_entire);
            free(options);
            return 1;
        }

        if (read_size < 8) {
            printf("ERROR: Input file is too small to contain valid plist data.\n");
	    free(plist_entire);
            free(options);
	    return 1;
	}
    }
    else
    {
	// read input file
	iplist = fopen(options->in_file, "rb");
        if (!iplist) {
            printf("ERROR: Could not open input file '%s': %s\n", options->in_file, strerror(errno));
            free(options);
            return 1;
        }

        memset(&filestats, '\0', sizeof(struct stat));
        fstat(fileno(iplist), &filestats);

        if (filestats.st_size < 8) {
            printf("ERROR: Input file is too small to contain valid plist data.\n");
            free(options);
            fclose(iplist);
            return -1;
        }

        plist_entire = (char *) malloc(sizeof(char) * (filestats.st_size + 1));
        read_size = fread(plist_entire, sizeof(char), filestats.st_size, iplist);
        fclose(iplist);
    }

    if (options->out_fmt == 0) {
        // convert from binary to xml or vice-versa<br>
        if (plist_is_binary(plist_entire, read_size))
        {
            plist_from_bin(plist_entire, read_size, &root_node);
            plist_to_xml(root_node, &plist_out, &size);
        }
        else
        {
            plist_from_xml(plist_entire, read_size, &root_node);
            plist_to_bin(root_node, &plist_out, &size);
        }
    }
    else
    {
        if (options->out_fmt == 1) {
            if (plist_is_binary(plist_entire, read_size))
            {
                plist_out = malloc(sizeof(char) * read_size);
                memcpy(plist_out, plist_entire, read_size);
                size = read_size;
            }
            else
            {
                plist_from_xml(plist_entire, read_size, &root_node);
                plist_to_bin(root_node, &plist_out, &size);
            }
        } else if (options->out_fmt == 2) {
            if (plist_is_binary(plist_entire, read_size)) {
                plist_from_bin(plist_entire, read_size, &root_node);
                plist_to_xml(root_node, &plist_out, &size);
            }
            else
            {
                plist_out = malloc(sizeof(char) * read_size);
                memcpy(plist_out, plist_entire, read_size);
                size = read_size;
            }
        }
    }
    plist_free(root_node);
    free(plist_entire);

    if (plist_out)
    {
        if (options->out_file != NULL && strcmp(options->out_file, "-"))
        {
            FILE *oplist = fopen(options->out_file, "wb");
            if (!oplist) {
                printf("ERROR: Could not open output file '%s': %s\n", options->out_file, strerror(errno));
                free(options);
                return 1;
            }
            fwrite(plist_out, size, sizeof(char), oplist);
            fclose(oplist);
        }
        // if no output file specified, write to stdout
        else
            fwrite(plist_out, size, sizeof(char), stdout);

        free(plist_out);
    }
    else
        printf("ERROR: Failed to convert input file.\n");

    free(options);
    return 0;
}
