/*
 * status-cmd.c -- Display status information in current directory
 *
 * ====================================================================
 *    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.
 * ====================================================================
 */

/* ==================================================================== */



/*** Includes. ***/

#include "svn_string.h"
#include "svn_wc.h"
#include "svn_client.h"
#include "svn_error_codes.h"
#include "svn_error.h"
#include "svn_pools.h"
#include "svn_xml.h"
#include "svn_dirent_uri.h"
#include "svn_path.h"
#include "svn_cmdline.h"
#include "cl.h"

#include "svn_private_config.h"
#include "private/svn_wc_private.h"



/*** Code. ***/

struct status_baton
{
  /* These fields all correspond to the ones in the
     svn_cl__print_status() interface. */
  svn_boolean_t detailed;
  svn_boolean_t show_last_committed;
  svn_boolean_t skip_unrecognized;
  svn_boolean_t repos_locks;

  apr_hash_t *cached_changelists;
  apr_pool_t *cl_pool;          /* where cached changelists are allocated */

  svn_boolean_t had_print_error;  /* To avoid printing lots of errors if we get
                                     errors while printing to stdout */
  svn_boolean_t xml_mode;

  /* Conflict stats. */
  unsigned int text_conflicts;
  unsigned int prop_conflicts;
  unsigned int tree_conflicts;

  svn_client_ctx_t *ctx;
};


struct status_cache
{
  const char *path;
  svn_client_status_t *status;
};

/* Print conflict stats accumulated in status baton SB.
 * Do temporary allocations in POOL. */
static svn_error_t *
print_conflict_stats(struct status_baton *sb, apr_pool_t *pool)
{
  if (sb->text_conflicts > 0 || sb->prop_conflicts > 0 ||
      sb->tree_conflicts > 0)
      SVN_ERR(svn_cmdline_printf(pool, "%s", _("Summary of conflicts:\n")));

  if (sb->text_conflicts > 0)
    SVN_ERR(svn_cmdline_printf
      (pool, _("  Text conflicts: %u\n"), sb->text_conflicts));

  if (sb->prop_conflicts > 0)
    SVN_ERR(svn_cmdline_printf
      (pool, _("  Property conflicts: %u\n"), sb->prop_conflicts));

  if (sb->tree_conflicts > 0)
    SVN_ERR(svn_cmdline_printf
      (pool, _("  Tree conflicts: %u\n"), sb->tree_conflicts));

  return SVN_NO_ERROR;
}

/* Prints XML target element with path attribute TARGET, using POOL for
   temporary allocations. */
static svn_error_t *
print_start_target_xml(const char *target, apr_pool_t *pool)
{
  svn_stringbuf_t *sb = svn_stringbuf_create("", pool);

  svn_xml_make_open_tag(&sb, pool, svn_xml_normal, "target",
                        "path", target, NULL);

  return svn_cl__error_checked_fputs(sb->data, stdout);
}


/* Finish a target element by optionally printing an against element if
 * REPOS_REV is a valid revision number, and then printing an target end tag.
 * Use POOL for temporary allocations. */
static svn_error_t *
print_finish_target_xml(svn_revnum_t repos_rev,
                        apr_pool_t *pool)
{
  svn_stringbuf_t *sb = svn_stringbuf_create("", pool);

  if (SVN_IS_VALID_REVNUM(repos_rev))
    {
      const char *repos_rev_str;
      repos_rev_str = apr_psprintf(pool, "%ld", repos_rev);
      svn_xml_make_open_tag(&sb, pool, svn_xml_self_closing, "against",
                            "revision", repos_rev_str, NULL);
    }

  svn_xml_make_close_tag(&sb, pool, "target");

  return svn_cl__error_checked_fputs(sb->data, stdout);
}


/* Function which *actually* causes a status structure to be output to
   the user.  Called by both print_status() and svn_cl__status(). */
static svn_error_t *
print_status_normal_or_xml(void *baton,
                           const char *path,
                           const svn_client_status_t *status,
                           apr_pool_t *pool)
{
  struct status_baton *sb = baton;

  if (sb->xml_mode)
    return svn_cl__print_status_xml(path, status, sb->ctx, pool);
  else
    return svn_cl__print_status(path, status, sb->detailed,
                                sb->show_last_committed,
                                sb->skip_unrecognized,
                                sb->repos_locks,
                                &sb->text_conflicts,
                                &sb->prop_conflicts,
                                &sb->tree_conflicts,
                                sb->ctx,
                                pool);
}


/* A status callback function for printing STATUS for PATH. */
static svn_error_t *
print_status(void *baton,
             const char *path,
             const svn_client_status_t *status,
             apr_pool_t *pool)
{
  struct status_baton *sb = baton;

  svn_revnum_t revision;
  svn_revnum_t changed_rev;
  apr_time_t changed_date;
  const char *changed_author;
  const char *local_abspath;

  local_abspath = status->local_abspath;

  /* ### The revision information with associates are based on what
   * ### _read_info() returns. The svn_wc_status_func4_t callback is
   * ### suppposed to handle the gathering of additional information from the
   * ### WORKING nodes on its own. Until we've agreed on how the CLI should
   * ### handle the revision information, we use this appproach to stay compat
   * ### with our testsuite. */
  if (status->versioned
      && !SVN_IS_VALID_REVNUM(status->revision)
      && !status->copied)
    {
      svn_client_status_t *tweaked_status
                 = svn_client_status_dup(status, sb->cl_pool);

      /* Retrieve some data from the original version of the replaced node */
      SVN_ERR(svn_wc__node_get_working_rev_info(&revision, &changed_rev,
                                                &changed_date,
                                                &changed_author,
                                                sb->ctx->wc_ctx,
                                                local_abspath, sb->cl_pool,
                                                pool));
      tweaked_status->revision = revision;
      tweaked_status->changed_rev = changed_rev;
      tweaked_status->changed_date = changed_date;
      tweaked_status->changed_author = changed_author;

      status = tweaked_status;
    }

  /* If the path is part of a changelist, then we don't print
     the item, but instead dup & cache the status structure for later. */
  if (status->changelist)
    {
      /* The hash maps a changelist name to an array of status_cache
         structures. */
      apr_array_header_t *path_array;
      const char *cl_key = apr_pstrdup(sb->cl_pool, status->changelist);
      struct status_cache *scache = apr_pcalloc(sb->cl_pool, sizeof(*scache));
      scache->path = apr_pstrdup(sb->cl_pool, path);
      scache->status = svn_client_status_dup(status, sb->cl_pool);

      path_array =
        apr_hash_get(sb->cached_changelists, cl_key, APR_HASH_KEY_STRING);
      if (path_array == NULL)
        {
          path_array = apr_array_make(sb->cl_pool, 1,
                                      sizeof(struct status_cache *));
          apr_hash_set(sb->cached_changelists, cl_key,
                       APR_HASH_KEY_STRING, path_array);
        }

      APR_ARRAY_PUSH(path_array, struct status_cache *) = scache;
      return SVN_NO_ERROR;
    }

  return print_status_normal_or_xml(baton, path, status, pool);
}

/* This implements the `svn_opt_subcommand_t' interface. */
svn_error_t *
svn_cl__status(apr_getopt_t *os,
               void *baton,
               apr_pool_t *scratch_pool)
{
  svn_cl__opt_state_t *opt_state = ((svn_cl__cmd_baton_t *) baton)->opt_state;
  svn_client_ctx_t *ctx = ((svn_cl__cmd_baton_t *) baton)->ctx;
  apr_array_header_t *targets;
  apr_pool_t *iterpool;
  apr_hash_t *master_cl_hash = apr_hash_make(scratch_pool);
  int i;
  svn_opt_revision_t rev;
  struct status_baton sb;

  SVN_ERR(svn_cl__args_to_target_array_print_reserved(&targets, os,
                                                      opt_state->targets,
                                                      ctx, scratch_pool));

  /* Add "." if user passed 0 arguments */
  svn_opt_push_implicit_dot_target(targets, scratch_pool);

  /* We want our -u statuses to be against HEAD. */
  rev.kind = svn_opt_revision_head;

  sb.had_print_error = FALSE;

  if (opt_state->xml)
    {
      /* If output is not incremental, output the XML header and wrap
         everything in a top-level element. This makes the output in
         its entirety a well-formed XML document. */
      if (! opt_state->incremental)
        SVN_ERR(svn_cl__xml_print_header("status", scratch_pool));
    }
  else
    {
      if (opt_state->incremental)
        return svn_error_create(SVN_ERR_CL_ARG_PARSING_ERROR, NULL,
                                _("'incremental' option only valid in XML "
                                  "mode"));
    }

  sb.detailed = (opt_state->verbose || opt_state->update);
  sb.show_last_committed = opt_state->verbose;
  sb.skip_unrecognized = opt_state->quiet;
  sb.repos_locks = opt_state->update;
  sb.xml_mode = opt_state->xml;
  sb.cached_changelists = master_cl_hash;
  sb.cl_pool = scratch_pool;
  sb.text_conflicts = 0;
  sb.prop_conflicts = 0;
  sb.tree_conflicts = 0;
  sb.ctx = ctx;

  SVN_ERR(svn_cl__eat_peg_revisions(&targets, targets, scratch_pool));

  iterpool = svn_pool_create(scratch_pool);
  for (i = 0; i < targets->nelts; i++)
    {
      const char *target = APR_ARRAY_IDX(targets, i, const char *);
      svn_revnum_t repos_rev = SVN_INVALID_REVNUM;

      svn_pool_clear(iterpool);

      SVN_ERR(svn_cl__check_cancel(ctx->cancel_baton));

      if (opt_state->xml)
        SVN_ERR(print_start_target_xml(svn_dirent_local_style(target, iterpool),
                                       iterpool));

      /* Retrieve a hash of status structures with the information
         requested by the user. */
      SVN_ERR(svn_cl__try(svn_client_status5(&repos_rev, ctx, target, &rev,
                                             opt_state->depth,
                                             opt_state->verbose,
                                             opt_state->update,
                                             opt_state->no_ignore,
                                             opt_state->ignore_externals,
                                             FALSE /* depth_as_sticky */,
                                             opt_state->changelists,
                                             print_status, &sb,
                                             iterpool),
                          NULL, opt_state->quiet,
                          /* not versioned: */
                          SVN_ERR_WC_NOT_WORKING_COPY,
                          SVN_NO_ERROR));

      if (opt_state->xml)
        SVN_ERR(print_finish_target_xml(repos_rev, iterpool));
    }

  /* If any paths were cached because they were associatied with
     changelists, we can now display them as grouped changelists. */
  if (apr_hash_count(master_cl_hash) > 0)
    {
      apr_hash_index_t *hi;
      svn_stringbuf_t *buf;

      if (opt_state->xml)
        buf = svn_stringbuf_create("", scratch_pool);

      for (hi = apr_hash_first(scratch_pool, master_cl_hash); hi;
           hi = apr_hash_next(hi))
        {
          const char *changelist_name = svn__apr_hash_index_key(hi);
          apr_array_header_t *path_array = svn__apr_hash_index_val(hi);
          int j;

          /* ### TODO: For non-XML output, we shouldn't print the
             ### leading \n on the first changelist if there were no
             ### non-changelist entries. */
          if (opt_state->xml)
            {
              svn_stringbuf_set(buf, "");
              svn_xml_make_open_tag(&buf, scratch_pool, svn_xml_normal,
                                    "changelist", "name", changelist_name,
                                    NULL);
              SVN_ERR(svn_cl__error_checked_fputs(buf->data, stdout));
            }
          else
            SVN_ERR(svn_cmdline_printf(scratch_pool,
                                       _("\n--- Changelist '%s':\n"),
                                       changelist_name));

          for (j = 0; j < path_array->nelts; j++)
            {
              struct status_cache *scache =
                APR_ARRAY_IDX(path_array, j, struct status_cache *);
              SVN_ERR(print_status_normal_or_xml(&sb, scache->path,
                                                 scache->status, scratch_pool));
            }

          if (opt_state->xml)
            {
              svn_stringbuf_set(buf, "");
              svn_xml_make_close_tag(&buf, scratch_pool, "changelist");
              SVN_ERR(svn_cl__error_checked_fputs(buf->data, stdout));
            }
        }
    }
  svn_pool_destroy(iterpool);

  if (opt_state->xml && (! opt_state->incremental))
    SVN_ERR(svn_cl__xml_print_footer("status", scratch_pool));

  if (! opt_state->quiet && ! opt_state->xml)
      SVN_ERR(print_conflict_stats(&sb, scratch_pool));

  return SVN_NO_ERROR;
}
