/**
 * @file parens.cpp
 * Adds or removes parens.
 *
 * @author  Ben Gardner
 * @license GPL v2+
 */
#include "uncrustify_types.h"
#include "chunk_list.h"
#include "prototypes.h"
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cerrno>
#include "unc_ctype.h"


static void add_parens_between(chunk_t *first, chunk_t *last);
static void check_bool_parens(chunk_t *popen, chunk_t *pclose, int nest);


void do_parens(void)
{
   LOG_FUNC_ENTRY();
   chunk_t *pc;
   chunk_t *pclose;

   if (cpd.settings[UO_mod_full_paren_if_bool].b)
   {
      pc = chunk_get_head();
      while ((pc = chunk_get_next_ncnl(pc)) != NULL)
      {
         if ((pc->type != CT_SPAREN_OPEN) ||
             ((pc->parent_type != CT_IF) &&
              (pc->parent_type != CT_ELSEIF) &&
              (pc->parent_type != CT_SWITCH)))
         {
            continue;
         }

         /* Grab the close sparen */
         pclose = chunk_get_next_type(pc, CT_SPAREN_CLOSE, pc->level, CNAV_PREPROC);
         if (pclose != NULL)
         {
            check_bool_parens(pc, pclose, 0);
            pc = pclose;
         }
      }
   }
}


/**
 * Add an open paren after first and add a close paren before the last
 */
static void add_parens_between(chunk_t *first, chunk_t *last)
{
   LOG_FUNC_ENTRY();
   chunk_t pc;
   chunk_t *first_n;
   chunk_t *last_p;
   chunk_t *tmp;

   LOG_FMT(LPARADD, "%s: line %d between %s [lvl=%d] and %s [lvl=%d]\n",
           __func__, first->orig_line,
           first->str.c_str(), first->level,
           last->str.c_str(), last->level);

   /* Don't do anything if we have a bad sequence, ie "&& )" */
   first_n = chunk_get_next_ncnl(first);
   if (first_n == last)
   {
      return;
   }

   pc.type        = CT_PAREN_OPEN;
   pc.str         = "(";
   pc.flags       = first_n->flags & PCF_COPY_FLAGS;
   pc.level       = first_n->level;
   pc.pp_level    = first_n->pp_level;
   pc.brace_level = first_n->brace_level;

   chunk_add_before(&pc, first_n);

   last_p         = chunk_get_prev_ncnl(last, CNAV_PREPROC);
   pc.type        = CT_PAREN_CLOSE;
   pc.str         = ")";
   pc.flags       = last_p->flags & PCF_COPY_FLAGS;
   pc.level       = last_p->level;
   pc.pp_level    = last_p->pp_level;
   pc.brace_level = last_p->brace_level;

   chunk_add_after(&pc, last_p);

   for (tmp = first_n;
        tmp != last_p;
        tmp = chunk_get_next_ncnl(tmp))
   {
      tmp->level++;
   }
   last_p->level++;
}


/**
 * Scans between two parens and adds additional parens if needed.
 * This function is recursive. If it hits another open paren, it'll call itself
 * with the new bounds.
 *
 * Adds optional parens in an IF or SWITCH conditional statement.
 *
 * This basically just checks for a CT_COMPARE that isn't surrounded by parens.
 * The edges for the compare are the open, close and any CT_BOOL tokens.
 *
 * This only handleds VERY simple patterns:
 *   (!a && b)         => (!a && b)          -- no change
 *   (a && b == 1)     => (a && (b == 1))
 *   (a == 1 || b > 2) => ((a == 1) || (b > 2))
 *
 * FIXME: we really should bail if we transition between a preprocessor and
 *        a non-preprocessor
 */
static void check_bool_parens(chunk_t *popen, chunk_t *pclose, int nest)
{
   LOG_FUNC_ENTRY();
   chunk_t *pc;
   chunk_t *ref = popen;
   chunk_t *next;
   bool    hit_compare = false;

   LOG_FMT(LPARADD, "%s(%d): popen on %d, col %d, pclose on %d, col %d, level=%d\n",
           __func__, nest,
           popen->orig_line, popen->orig_col,
           pclose->orig_line, pclose->orig_col,
           popen->level);

   pc = popen;
   while (((pc = chunk_get_next_ncnl(pc)) != NULL) && (pc != pclose))
   {
      if (pc->flags & PCF_IN_PREPROC)
      {
         LOG_FMT(LPARADD2, " -- bail on PP %s [%s] at line %d col %d, level %d\n",
                 get_token_name(pc->type),
                 pc->str.c_str(), pc->orig_line, pc->orig_col, pc->level);
         return;
      }

      if ((pc->type == CT_BOOL) ||
          (pc->type == CT_QUESTION) ||
          (pc->type == CT_COND_COLON) ||
          (pc->type == CT_COMMA))
      {
         LOG_FMT(LPARADD2, " -- %s [%s] at line %d col %d, level %d\n",
                 get_token_name(pc->type),
                 pc->str.c_str(), pc->orig_line, pc->orig_col, pc->level);
         if (hit_compare)
         {
            hit_compare = false;
            add_parens_between(ref, pc);
         }
         ref = pc;
      }
      else if (pc->type == CT_COMPARE)
      {
         LOG_FMT(LPARADD2, " -- compare [%s] at line %d col %d, level %d\n",
                 pc->str.c_str(), pc->orig_line, pc->orig_col, pc->level);
         hit_compare = true;
      }
      else if (chunk_is_paren_open(pc))
      {
         next = chunk_skip_to_match(pc);
         if (next != NULL)
         {
            check_bool_parens(pc, next, nest + 1);
            pc = next;
         }
      }
      else if ((pc->type == CT_BRACE_OPEN) ||
               (pc->type == CT_SQUARE_OPEN) ||
               (pc->type == CT_ANGLE_OPEN))
      {
         /* Skip [], {}, and <> */
         pc = chunk_skip_to_match(pc);
      }
   }

   if (hit_compare && (ref != popen))
   {
      add_parens_between(ref, pclose);
   }
}
