/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package org.apache.gearpump.cluster.main

import org.apache.gearpump.cluster.main.ArgumentsParser.Syntax

case class CLIOption[+T](
    description: String = "", required: Boolean = false, defaultValue: Option[T] = None)

class ParseResult(optionMap: Map[String, String], remainArguments: Array[String]) {
  def getInt(key: String): Int = optionMap(key).toInt

  def getString(key: String): String = optionMap(key)

  def getBoolean(key: String): Boolean = optionMap(key).toBoolean

  def exists(key: String): Boolean = !optionMap.getOrElse(key, "").isEmpty

  def remainArgs: Array[String] = this.remainArguments
}

/**
 * Parser for command line arguments
 *
 * Grammar: -option1 value1 -option2 value3 -flag1 -flag2 remainArg1 remainArg2...
 */
trait ArgumentsParser {

  val ignoreUnknownArgument = false

  // scalastyle:off println
  def help(): Unit = {
    Console.println(s"\nHelp: $description")
    val usage = options.map(kv => if (kv._2.required) {
      s"-${kv._1} (required:${kv._2.required})${kv._2.description}"
    } else {
      s"-${kv._1} (required:${kv._2.required}, " +
        s"default:${kv._2.defaultValue.getOrElse("")})${kv._2.description}"
    }) ++ remainArgs.map(k => s"<$k>").mkString(" ")
    usage.foreach(Console.println)
  }
  // scalastyle:on println

  def parse(args: Array[String]): ParseResult = {
    val syntax = Syntax(options, remainArgs, ignoreUnknownArgument)
    ArgumentsParser.parse(syntax, args)
  }

  val description: String = ""
  val options: Array[(String, CLIOption[Any])] = Array.empty[(String, CLIOption[Any])]
  val remainArgs: Array[String] = Array.empty[String]
}

object ArgumentsParser {

  case class Syntax(
      options: Array[(String, CLIOption[Any])],
      remainArgs: Array[String],
      ignoreUnknownArgument: Boolean)

  def parse(syntax: Syntax, args: Array[String]): ParseResult = {
    import syntax.{ignoreUnknownArgument, options, remainArgs}
    var config = Map.empty[String, String]
    var remain = Array.empty[String]

    @annotation.tailrec
    def doParse(argument: List[String]): Unit = {
      argument match {
        case Nil => Unit // true if everything processed successfully

        case key :: value :: rest if key.startsWith("-") && !value.startsWith("-") =>
          val fixedKey = key.substring(1)
          if (!options.map(_._1).contains(fixedKey)) {
            if (!ignoreUnknownArgument) {
              throw new Exception(s"found unknown option $fixedKey")
            } else {
              remain ++= Array(key, value)
            }
          } else {
            config += fixedKey -> value
          }
          doParse(rest)

        case key :: rest if key.startsWith("-") =>
          val fixedKey = key.substring(1)
          if (!options.map(_._1).contains(fixedKey)) {
            throw new Exception(s"found unknown option $fixedKey")
          } else {
            config += fixedKey -> "true"
          }
          doParse(rest)

        case value :: rest =>
          remain ++= value :: rest
          doParse(Nil)
      }
    }
    doParse(args.toList)

    options.foreach { pair =>
      val (key, option) = pair
      if (!config.contains(key) && !option.required) {
        config += key -> option.defaultValue.getOrElse("").toString
      }
    }

    options.foreach { case (key, _) =>
      if (config.get(key).isEmpty) {
        throw new Exception(s"Missing option $key...")
      }
    }

    if (remain.length < remainArgs.length) {
      throw new Exception(s"Missing arguments ...")
    }

    new ParseResult(config, remain)
  }
}