#ifndef STAN_LANG_GENERATOR_GENERATE_FUNCTION_ARGUMENTS_HPP
#define STAN_LANG_GENERATOR_GENERATE_FUNCTION_ARGUMENTS_HPP

#include <stan/lang/ast.hpp>
#include <stan/lang/generator/constants.hpp>
#include <stan/lang/generator/generate_arg_decl.hpp>
#include <boost/lexical_cast.hpp>
#include <ostream>
#include <string>

namespace stan {
  namespace lang {

    /**
     * Generate the arguments for the specified function, with
     * precalculated flags for whether it is an RNG, uses the log
     * density accumulator or is a probability function, to the
     * specified stream.
     *
     * @param[in] fun function declaration
     * @param[in] is_rng true if function is an RNG
     * @param[in] is_lp true if function accesses log density
     * accumulator
     * @param[in] is_log true if function is log probability function
     * @param[in,out] o stream for generating
     */
    void generate_function_arguments(const function_decl_def& fun, bool is_rng,
                                     bool is_lp, bool is_log, std::ostream& o) {
      o << "(";
      for (size_t i = 0; i < fun.arg_decls_.size(); ++i) {
        std::string template_type_i
          = "T" + boost::lexical_cast<std::string>(i) + "__";
        generate_arg_decl(true, true, fun.arg_decls_[i], template_type_i, o);
        if (i + 1 < fun.arg_decls_.size()) {
          o << "," << EOL << INDENT;
          for (size_t i = 0; i <= fun.name_.size(); ++i)
            o << " ";
        }
      }
      if ((is_rng || is_lp) && fun.arg_decls_.size() > 0)
        o << ", ";
      if (is_rng)
        o << "RNG& base_rng__";
      else if (is_lp)
        o << "T_lp__& lp__, T_lp_accum__& lp_accum__";
      if (is_rng || is_lp || fun.arg_decls_.size() > 0)
        o << ", ";
      o << "std::ostream* pstream__";
      o << ")";
    }

  }
}
#endif
