/* Copyright (c) 2018, NVIDIA CORPORATION.  All rights reserved.
 *
 * NVIDIA CORPORATION and its licensors retain all intellectual property
 * and proprietary rights in and to this software, related documentation
 * and any modifications thereto.  Any use, reproduction, disclosure or
 * distribution of this software and related documentation without an express
 * license agreement from NVIDIA CORPORATION is strictly prohibited.
 */

#include <ctype.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>

#include "cmdline.h"
#include "log_utils.h"
#include "misc_utils.h"

#define SURFACE_TYPE_NONE 0 // Default surface type attribute init value

int
ParseArgs (
    int argc,
    char *argv[],
    TestArgs *args)
{
    int i = 0;
    NvMediaBool bLastArg = NVMEDIA_FALSE;
    NvMediaBool bDataAvailable = NVMEDIA_FALSE;

    // Default params
    args->inputWidth = 1280;
    args->inputHeight = 1080;
    args->inputSurfType = SURFACE_TYPE_NONE;
    args->loop = 1;
    args->outputWidth = 1280;
    args->outputHeight = 1080;
    args->outputSurfType = NVM_SURF_ATTR_SURF_TYPE_RGBA;

    // First look for help request, logging level and configuration file name.
    if(argc >= 2) {
        for(i = 1; i < argc; i++) {
            // check if this is the last argument
            bLastArg = ((argc - i) == 1);

            // check if there is data available to be parsed
            bDataAvailable = (!bLastArg) && !(argv[i+1][0] == '-');

            if(!strcasecmp(argv[i], "-h")) {
                PrintUsage();
                return 1;
            } else if(!strcasecmp(argv[i], "-v")) {
                args->logLevel = LEVEL_DBG;
                if(bDataAvailable) {
                    args->logLevel = atoi(argv[++i]);
                    if(args->logLevel < LEVEL_ERR ||
                       args->logLevel > LEVEL_DBG) {
                        printf("Invalid logging level chosen (%d)\n",
                               args->logLevel);
                        printf("Setting logging level to LEVEL_ERR (0)\n");
                        args->logLevel = LEVEL_ERR;
                    }
                }
                SetLogLevel(args->logLevel);
            }
        }
    }

    // The rest
    if(argc >= 2) {
       for(i = 1; i < argc; i++) {
       // check if this is the last argument
          bLastArg = ((argc - i) == 1);

         // check if there is data available to be parsed
         bDataAvailable = (!bLastArg) && (argv[i+1][0] != '-');

         if(strcasecmp(&argv[i][1], "h") == 0) {
            PrintUsage();
            return 1;
         } else if(strcasecmp(argv[i], "-v") == 0) {
            if(bDataAvailable)
               ++i;
         } else if(!strcasecmp(argv[i], "-oddfieldfile")) {
            if(bDataAvailable) {
               ++i;
               args->inputFileName1 = argv[i];
            }
         } else if(!strcasecmp(argv[i], "-evenfieldfile")) {
            if(bDataAvailable) {
               ++i;
               args->inputFileName2 = argv[i];
            }
         } else if(!strcasecmp(argv[i], "-outfile")) {
            if(bDataAvailable) {
               ++i;
               args->outputFileName = argv[i];
            } else {
               LOG_ERR("-outfile must be followed by output file name\n");
               return -1;
            }
         } else if(!strcasecmp(argv[i], "-it")) {
            if(bDataAvailable) {
               ++i;
               if(!strcasecmp(argv[i], "rgba")) {
                  args->inputSurfType = NVM_SURF_ATTR_SURF_TYPE_RGBA;
               } else if(!strcasecmp(argv[i], "8bpp")) {
                  args->inputSurfType = NVM_SURF_ATTR_SURF_TYPE_RAW;
               } else {
                  LOG_ERR("Unsupported input type\n");
                  return -1;
               }
            }
         } else if(!strcasecmp(argv[i], "-ir")) {
            if(bDataAvailable) {
               if((sscanf(argv[++i],
                          "%ux%u",
                          &args->inputWidth,
                          &args->inputHeight) != 2)) {
                  LOG_ERR("Bad input resolution: %s\n", argv[i]);
                  return -1;
               }
            } else {
               LOG_ERR("-ir must be followed by resolution\n");
               return -1;
            }
         } else {
            LOG_ERR("Unsupported option encountered: %s\n", argv[i]);
            return -1;
         }
       }
    }

    if(!args->inputFileName1 || !args->inputFileName2) {
       LOG_ERR("%s: missing input file name\n", __func__);
       return -1;
    }

    return 0;
}

void
PrintUsage ()
{

    LOG_MSG("Usage: nvmimg_weave2d\n");
    LOG_MSG("\nAvailable command line options:\n");
    LOG_MSG("-h                Print usage\n");
    LOG_MSG("-v [level]        Logging Level. Default = 0\n");
    LOG_MSG("                  0: Errors, : Warnings, 2: Info, 3: Debug\n");
    LOG_MSG("                  Default: 0\n");
    LOG_MSG("-evenfieldfile [even field file]         Input file name\n");
    LOG_MSG("-oddfieldfile  [odd field file]          Input file name\n");
    LOG_MSG("-ir [WxH]         Input resolution. Default: 1280x1080\n");
    LOG_MSG("-it               Input image type: rgba or 8bpp\n");
    LOG_MSG("-outfile [file]         Output file name\n");
}
