/*
 * Copyright © 2011-2012 Linaro Limited
 *
 * This file is part of glcompbench.
 *
 * glcompbench is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * glcompbench 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.
 *
 * You should have received a copy of the GNU General Public License
 * along with glcompbench.  If not, see <http://www.gnu.org/licenses/>.
 *
 * Authors:
 *  Alexandros Frantzis <alexandros.frantzis@linaro.org>
 *  Jesse Barker <jesse.barker@linaro.org>
 */

#include <cstring>
#include <cstdlib>
#include <cstdio>
#include <getopt.h>
#include <sstream>

#include "options.h"
#include "util.h"

std::vector<std::string> Options::benchmarks;
std::vector<std::string> Options::benchmark_files;
bool Options::validate = false;
Options::FrameEnd Options::frame_end = Options::FrameEndDefault;
std::pair<int,int> Options::size(800, 600);
bool Options::list_scenes = false;
bool Options::show_all_options = false;
bool Options::show_debug = false;
bool Options::show_help = false;
bool Options::reuse_context = false;
bool Options::run_forever = false;
bool Options::annotate = false;
bool Options::offscreen = false;
GLVisualConfig Options::visual_config;

static struct option long_options[] = {
    {"annotate", 0, 0, 0},
    {"benchmark", 1, 0, 0},
    {"benchmark-file", 1, 0, 0},
    {"validate", 0, 0, 0},
    {"frame-end", 1, 0, 0},
    {"off-screen", 0, 0, 0},
    {"visual-config", 1, 0, 0},
    {"reuse-context", 0, 0, 0},
    {"run-forever", 0, 0, 0},
    {"size", 1, 0, 0},
    {"fullscreen", 0, 0, 0},
    {"list-scenes", 0, 0, 0},
    {"show-all-options", 0, 0, 0},
    {"debug", 0, 0, 0},
    {"help", 0, 0, 0},
    {0, 0, 0, 0}
};

/**
 * Parses a size string of the form WxH
 *
 * @param str the string to parse
 * @param size the parsed size (width, height)
 */
static void
parse_size(const std::string &str, std::pair<int,int> &size)
{
    std::vector<std::string> d;
    Util::split(str, 'x', d);

    size.first = Util::fromString<int>(d[0]);

    /*
     * Parse the second element (height). If there is none, use the value
     * of the first element for the second (width = height)
     */
    if (d.size() > 1)
        size.second = Util::fromString<int>(d[1]);
    else
        size.second = size.first;
}

/**
 * Parses a frame-end method string
 *
 * @param str the string to parse
 *
 * @return the parsed frame end method
 */
static Options::FrameEnd 
frame_end_from_str(const std::string &str)
{
    Options::FrameEnd m = Options::FrameEndDefault;

    if (str == "swap")
        m = Options::FrameEndSwap;
    else if (str == "finish")
        m = Options::FrameEndFinish;
    else if (str == "readpixels")
        m = Options::FrameEndReadPixels;
    else if (str == "none")
        m = Options::FrameEndNone;

    return m;
}

void
Options::print_help()
{
    printf("A benchmark for Open GL (ES) 2.0\n"
           "\n"
           "Options:\n"
           "  -b, --benchmark BENCH  A benchmark to run: 'scene(:opt1=val1)*'\n"
           "                         (the option can be used multiple times)\n"
           "  -f, --benchmark-file F Load benchmarks to run from a file containing a\n"
           "                         list of benchmark descriptions (one per line)\n"
           "                         (the option can be used multiple times)\n"
           "      --validate         Run a quick output validation test instead of \n"
           "                         running the benchmarks\n"
           "      --frame-end METHOD How to end a frame [default,none,swap,finish,readpixels]\n"
           "      --off-screen       Render to an off-screen surface\n"
           "      --visual-config C  The visual configuration to use for the rendering\n"
           "                         target: 'red=R:green=G:blue=B:alpha=A:buffer=BUF'.\n"
           "                         The parameters may be defined in any order, and any\n"
           "                         omitted parameters assume a default value of '1'\n"
           "      --reuse-context    Use a single context for all scenes\n"
           "                         (by default, each scene gets its own context)\n"
           "  -s, --size WxH         Size of the output window (default: 800x600)\n"
           "      --fullscreen       Run in fullscreen mode (equivalent to --size -1x-1)\n"
           "  -l, --list-scenes      Display information about the available scenes\n"
           "                         and their options\n"
           "      --show-all-options Show all scene option values used for benchmarks\n"
           "                         (only explicitly set options are shown by default)\n"
           "      --run-forever      Run indefinitely, looping from the last benchmark\n"
           "                         back to the first\n"
           "      --annotate         Annotate the benchmarks with on-screen information\n"
           "                         (same as -b :show-fps=true:title=#info#)\n"
           "  -d, --debug            Display debug messages\n"
           "  -h, --help             Display help\n");
}

bool
Options::parse_args(int argc, char **argv)
{
    while (1) {
        int option_index = -1;
        int c;
        const char *optname = "";

        c = getopt_long(argc, argv, "b:f:s:ldh",
                        long_options, &option_index);
        if (c == -1)
            break;
        if (c == ':' || c == '?')
            return false;

        if (option_index != -1)
            optname = long_options[option_index].name;

        if (!strcmp(optname, "annotate"))
            Options::annotate = true;
        if (c == 'b' || !strcmp(optname, "benchmark"))
            Options::benchmarks.push_back(optarg);
        else if (c == 'f' || !strcmp(optname, "benchmark-file"))
            Options::benchmark_files.push_back(optarg);
        else if (!strcmp(optname, "validate"))
            Options::validate = true;
        else if (!strcmp(optname, "frame-end"))
            Options::frame_end = frame_end_from_str(optarg);
        else if (!strcmp(optname, "off-screen"))
            Options::offscreen = true;
        else if (!strcmp(optname, "visual-config"))
            Options::visual_config = GLVisualConfig(optarg);
        else if (!strcmp(optname, "reuse-context"))
            Options::reuse_context = true;
        else if (c == 's' || !strcmp(optname, "size"))
            parse_size(optarg, Options::size);
        else if (!strcmp(optname, "fullscreen"))
            Options::size = std::pair<int,int>(-1, -1);
        else if (c == 'l' || !strcmp(optname, "list-scenes"))
            Options::list_scenes = true;
        else if (!strcmp(optname, "show-all-options"))
            Options::show_all_options = true;
        else if (!strcmp(optname, "run-forever"))
            Options::run_forever = true;
        else if (c == 'd' || !strcmp(optname, "debug"))
            Options::show_debug = true;
        else if (c == 'h' || !strcmp(optname, "help"))
            Options::show_help = true;
    }

    return true;
}
