/**
 * @file align_stack.cpp
 * Manages a align stack, which is just a pair of chunk stacks.
 * There can be at most 1 item per line in the stack.
 * The seqnum is actually a line counter.
 *
 * @author  Ben Gardner
 * @license GPL v2+
 */
#include "align_stack.h"
#include "prototypes.h"
#include "chunk_list.h"

/**
 * Resets the two ChunkLists and zeroes local vars.
 *
 * @param span    The row span limit
 * @param thresh  The column threshold
 */
void AlignStack::Start(int span, int thresh)
{
   LOG_FMT(LAS, "Start(%d, %d)\n", span, thresh);

   m_aligned.Reset();
   m_skipped.Reset();
   m_span        = span;
   m_thresh      = thresh;
   m_min_col     = 9999;
   m_max_col     = 0;
   m_nl_seqnum   = 0;
   m_seqnum      = 0;
   m_gap         = 0;
   m_right_align = false;
   m_star_style  = SS_IGNORE;
   m_amp_style   = SS_IGNORE;
}


/**
 * Calls Add on all the skipped items
 */
void AlignStack::ReAddSkipped()
{
   if (!m_skipped.Empty())
   {
      /* Make a copy of the ChunkStack and clear m_skipped */
      m_scratch.Set(m_skipped);
      m_skipped.Reset();

      const ChunkStack::Entry *ce;

      /* Need to add them in order so that m_nl_seqnum is correct */
      for (int idx = 0; idx < m_scratch.Len(); idx++)
      {
         ce = m_scratch.Get(idx);
         LOG_FMT(LAS, "ReAddSkipped [%d] - ", ce->m_seqnum);
         Add(ce->m_pc, ce->m_seqnum);
      }

      /* Check to see if we need to flush right away */
      NewLines(0);
   }
}


/**
 * Adds an entry to the appropriate stack.
 *
 * @param pc      The chunk
 * @param seqnum  Optional seqnum (0=assign one)
 */
void AlignStack::Add(chunk_t *start, int seqnum)
{
   LOG_FUNC_ENTRY();
   /* Assign a seqnum if needed */
   if (seqnum == 0)
   {
      seqnum = m_seqnum;
   }

   chunk_t *ali;
   chunk_t *ref;
   chunk_t *tmp;
   chunk_t *prev;
   chunk_t *next;

   int col_adj = 0;  /* Amount the column is shifted for 'dangle' mode */
   int tmp_col;
   int endcol;
   int gap;

   m_last_added = 0;

   /* Check threshold limits */
   if ((m_max_col == 0) || (m_thresh == 0) ||
       (((start->column + m_gap) <= (m_max_col + m_thresh)) &&
        (((start->column + m_gap) >= (m_max_col - m_thresh)) ||
         (start->column >= m_min_col))))
   {
      /* we are adding it, so update the newline seqnum */
      if (seqnum > m_nl_seqnum)
      {
         m_nl_seqnum = seqnum;
      }

      /**
       * SS_IGNORE: no special handling of '*' or '&', only 'foo' is aligned
       *     void     foo;  // gap=5, 'foo' is aligned
       *     char *   foo;  // gap=3, 'foo' is aligned
       *     foomatic foo;  // gap=1, 'foo' is aligned
       *  The gap is the columns between 'foo' and the previous token.
       *  [void - foo], ['*' - foo], etc
       *
       * SS_INCLUDE: - space between variable and '*' or '&' is eaten
       *     void     foo;  // gap=5, 'foo' is aligned
       *     char     *foo; // gap=5, '*' is aligned
       *     foomatic foo;  // gap=1, 'foo' is aligned
       *  The gap is the columns between the first '*' or '&' before foo
       *  and the previous token. [void - foo], [char - '*'], etc
       *
       * SS_DANGLE: - space between variable and '*' or '&' is eaten
       *     void     foo;  // gap=5
       *     char    *bar;  // gap=5, as the '*' doesn't count
       *     foomatic foo;  // gap=1
       *  The gap is the columns between 'foo' and the chunk before the first
       *  '*' or '&'. [void - foo], [char - bar], etc
       *
       * If the gap < m_gap, then the column is bumped out by the difference.
       * So, if m_gap is 2, then the above would be:
       * SS_IGNORE:
       *     void      foo;  // gap=6
       *     char *    foo;  // gap=4
       *     foomatic  foo;  // gap=2
       * SS_INCLUDE:
       *     void      foo;  // gap=6
       *     char      *foo; // gap=6
       *     foomatic  foo;  // gap=2
       * SS_DANGLE:
       *     void      foo;  // gap=6
       *     char     *bar;  // gap=6, as the '*' doesn't count
       *     foomatic  foo;  // gap=2
       * Right aligned numbers:
       *     #define A    -1
       *     #define B   631
       *     #define C     3
       * Left aligned numbers:
       *     #define A     -1
       *     #define B     631
       *     #define C     3
       *
       * In the code below, pc is set to the item that is aligned.
       * In the above examples, that is 'foo', '*', '-', or 63.
       *
       * Ref is set to the last part of the type.
       * In the above examples, that is 'void', 'char', 'foomatic', 'A', or 'B'.
       *
       * The '*' and '&' can float between the two.
       *
       * If align_on_tabstop=true, then SS_DANGLE is changed to SS_INCLUDE.
       */

      if (cpd.settings[UO_align_on_tabstop].b && (m_star_style == SS_DANGLE))
      {
         m_star_style = SS_INCLUDE;
      }

      /* Find ref. Back up to the real item that is aligned. */
      prev = start;
      while (((prev = chunk_get_prev(prev)) != NULL) &&
             (chunk_is_star(prev) ||
              chunk_is_addr(prev) ||
              (prev->type == CT_TPAREN_OPEN)))
      {
         /* do nothing - we want prev when this exits */
      }
      ref = prev;
      if (chunk_is_newline(ref))
      {
         ref = chunk_get_next(ref);
      }

      /* Find the item that we are going to align. */
      ali = start;
      if (m_star_style != SS_IGNORE)
      {
         /* back up to the first '*' preceding the token */
         prev = chunk_get_prev(ali);
         while (chunk_is_star(prev))
         {
            ali  = prev;
            prev = chunk_get_prev(ali);
         }
         if (chunk_is_token(prev, CT_TPAREN_OPEN))
         {
            ali  = prev;
            prev = chunk_get_prev(ali);
         }
      }
      if (m_amp_style != SS_IGNORE)
      {
         /* back up to the first '&' preceding the token */
         prev = chunk_get_prev(ali);
         while (chunk_is_addr(prev))
         {
            ali  = prev;
            prev = chunk_get_prev(ali);
         }
      }

      /* Tighten down the spacing between ref and start */
      if (!cpd.settings[UO_align_keep_extra_space].b)
      {
          tmp_col = ref->column;
          tmp     = ref;
          while (tmp != start)
          {
              next     = chunk_get_next(tmp);
              tmp_col += space_col_align(tmp, next);
              if (next->column != tmp_col)
              {
                  align_to_column(next, tmp_col);
              }
              tmp = next;
          }
      }

      /* Set the column adjust and gap */
      col_adj = 0;
      gap     = 0;
      if (ref != ali)
      {
         gap = ali->column - (ref->column + ref->len());
      }
      tmp = ali;
      if (chunk_is_token(tmp, CT_TPAREN_OPEN))
      {
         tmp = chunk_get_next(tmp);
      }
      if ((chunk_is_star(tmp) && (m_star_style == SS_DANGLE)) ||
          (chunk_is_addr(tmp) && (m_amp_style == SS_DANGLE)))
      {
         col_adj = start->column - ali->column;
         gap     = start->column - (ref->column + ref->len());
      }

      /* See if this pushes out the max_col */
      endcol = ali->column + col_adj;
      if (gap < m_gap)
      {
         endcol += m_gap - gap;
      }

      // LOG_FMT(LSYS, "[%p] line %d pc='%s' [%s] col:%d ali='%s' [%s] col:%d ref='%s' [%s] col:%d  col_adj=%d  endcol=%d, ss=%d as=%d, gap=%d\n",
      //         this,
      //         start->orig_line,
      //         start->str.c_str(), get_token_name(start->type), start->column,
      //         ali->str.c_str(), get_token_name(ali->type), ali->column,
      //         ref->str.c_str(), get_token_name(ref->type), ref->column,
      //         col_adj, endcol, m_star_style, m_amp_style, gap);

      ali->align.col_adj = col_adj;
      ali->align.ref     = ref;
      ali->align.start   = start;
      m_aligned.Push_Back(ali, seqnum);
      m_last_added = 1;

      LOG_FMT(LAS, "Add-[%s]: line %d, col %d, adj %d : ref=[%s] endcol=%d\n",
              ali->str.c_str(), ali->orig_line, ali->column, ali->align.col_adj,
              ref->str.c_str(), endcol);

      if (m_min_col > endcol)
      {
         m_min_col = endcol;
      }

      if (endcol > m_max_col)
      {
         LOG_FMT(LAS, "Add-aligned [%d/%d/%d]: line %d, col %d : max_col old %d, new %d - min_col %d\n",
                 seqnum, m_nl_seqnum, m_seqnum,
                 ali->orig_line, ali->column, m_max_col, endcol, m_min_col);
         m_max_col = endcol;

         /**
          * If there were any entries that were skipped, re-add them as they
          * may now be within the threshold
          */
         if (!m_skipped.Empty())
         {
            ReAddSkipped();
         }
      }
      else
      {
         LOG_FMT(LAS, "Add-aligned [%d/%d/%d]: line %d, col %d : col %d <= %d - min_col %d\n",
                 seqnum, m_nl_seqnum, m_seqnum,
                 ali->orig_line, ali->column, endcol, m_max_col, m_min_col);
      }
   }
   else
   {
      /* The threshold check failed, so add it to the skipped list */
      m_skipped.Push_Back(start, seqnum);
      m_last_added = 2;

      LOG_FMT(LAS, "Add-skipped [%d/%d/%d]: line %d, col %d <= %d + %d\n",
              seqnum, m_nl_seqnum, m_seqnum,
              start->orig_line, start->column, m_max_col, m_thresh);
   }
}


/**
 * Adds some newline and calls Flush() if needed
 */
void AlignStack::NewLines(int cnt)
{
   if (!m_aligned.Empty())
   {
      m_seqnum += cnt;
      if (m_seqnum > (m_nl_seqnum + m_span))
      {
         LOG_FMT(LAS, "Newlines<%d>-", cnt);
         Flush();
      }
      else
      {
         LOG_FMT(LAS, "Newlines<%d>\n", cnt);
      }
   }
}


/**
 * Aligns all the stuff in m_aligned.
 * Re-adds 'newer' items in m_skipped.
 */
void AlignStack::Flush()
{
   int last_seqnum = 0;
   int idx;
   int tmp_col;
   const ChunkStack::Entry *ce = NULL;
   chunk_t                 *pc;

   LOG_FMT(LAS, "Flush (min=%d, max=%d)\n", m_min_col, m_max_col);

   m_last_added = 0;
   m_max_col    = 0;

   /* Recalculate the max_col - it may have shifted since the last Add() */
   for (idx = 0; idx < m_aligned.Len(); idx++)
   {
      pc = m_aligned.Get(idx)->m_pc;

      /* Set the column adjust and gap */
      int col_adj = 0;
      int gap     = 0;
      if (pc != pc->align.ref)
      {
         gap = pc->column - (pc->align.ref->column + pc->align.ref->len());
      }
      chunk_t *tmp = pc;
      if (tmp->type == CT_TPAREN_OPEN)
      {
         tmp = chunk_get_next(tmp);
      }
      if ((chunk_is_star(tmp) && (m_star_style == SS_DANGLE)) ||
          (chunk_is_addr(tmp) && (m_amp_style == SS_DANGLE)))
      {
         col_adj = pc->align.start->column - pc->column;
         gap     = pc->align.start->column - (pc->align.ref->column + pc->align.ref->len());
      }
      if (m_right_align)
      {
         /* Adjust the width for signed numbers */
         int start_len = pc->align.start->len();
         if (pc->align.start->type == CT_NEG)
         {
            tmp = chunk_get_next(pc->align.start);
            if ((tmp != NULL) && (tmp->type == CT_NUMBER))
            {
               start_len += tmp->len();
            }
         }
         col_adj += start_len;
      }

      pc->align.col_adj = col_adj;

      /* See if this pushes out the max_col */
      int endcol = pc->column + col_adj;
      if (gap < m_gap)
      {
         endcol += m_gap - gap;
      }
      if (endcol > m_max_col)
      {
         m_max_col = endcol;
      }
   }

   if (cpd.settings[UO_align_on_tabstop].b && (m_aligned.Len() > 1))
   {
      m_max_col = align_tab_column(m_max_col);
   }

   for (idx = 0; idx < m_aligned.Len(); idx++)
   {
      ce = m_aligned.Get(idx);
      pc = ce->m_pc;

      tmp_col = m_max_col - pc->align.col_adj;
      if (idx == 0)
      {
         if (m_skip_first && (pc->column != tmp_col))
         {
            LOG_FMT(LAS, "%s: %d:%d dropping first item due to skip_first\n", __func__,
                    pc->orig_line, pc->orig_col);
            m_skip_first = false;
            m_aligned.Pop_Front();
            Flush();
            m_skip_first = true;
            return;
         }
         pc->flags |= PCF_ALIGN_START;

         pc->align.right_align = m_right_align;
         pc->align.amp_style   = (int)m_amp_style;
         pc->align.star_style  = (int)m_star_style;
      }
      pc->align.gap  = m_gap;
      pc->align.next = m_aligned.GetChunk(idx + 1);

      /* Indent the token, taking col_adj into account */
      LOG_FMT(LAS, "%s: line %d: '%s' to col %d (adj=%d)\n", __func__,
              pc->orig_line, pc->str.c_str(), tmp_col, pc->align.col_adj);
      align_to_column(pc, tmp_col);
   }

   if (ce != NULL)
   {
      last_seqnum = ce->m_seqnum;
      m_aligned.Reset();
   }
   m_min_col = 9999;
   m_max_col = 0;

   if (m_skipped.Empty())
   {
      /* Nothing was skipped, sync the seqnums */
      m_nl_seqnum = m_seqnum;
   }
   else
   {
      /* Remove all items with seqnum < last_seqnum */
      for (idx = 0; idx < m_skipped.Len(); idx++)
      {
         if (m_skipped.Get(idx)->m_seqnum < last_seqnum)
         {
            m_skipped.Zap(idx);
         }
      }
      m_skipped.Collapse();

      /* Add all items from the skipped list */
      ReAddSkipped();
   }
}


/**
 * Resets the stack, discarding anything that was previously added
 */
void AlignStack::Reset()
{
   m_aligned.Reset();
   m_skipped.Reset();
}


/**
 * Aligns everything else and resets the lists.
 */
void AlignStack::End()
{
   if (!m_aligned.Empty())
   {
      LOG_FMT(LAS, "End-");
      Flush();
   }

   m_aligned.Reset();
   m_skipped.Reset();
}
