/*
 * merge-cmd.c -- Merging changes into a working copy.
 *
 * ====================================================================
 *    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_client.h"
#include "svn_dirent_uri.h"
#include "svn_path.h"
#include "svn_error.h"
#include "svn_types.h"
#include "cl.h"
#include "private/svn_client_private.h"

#include "svn_private_config.h"


/*** Code. ***/

/* Throw an error if PATH_OR_URL is a path and REVISION isn't a repository
 * revision. */
static svn_error_t *
ensure_wc_path_has_repo_revision(const char *path_or_url,
                                 const svn_opt_revision_t *revision,
                                 apr_pool_t *scratch_pool)
{
  if (revision->kind != svn_opt_revision_number
      && revision->kind != svn_opt_revision_date
      && revision->kind != svn_opt_revision_head
      && ! svn_path_is_url(path_or_url))
    return svn_error_createf(
      SVN_ERR_CLIENT_BAD_REVISION, NULL,
      _("Invalid merge source '%s'; a working copy path can only be "
        "used with a repository revision (a number, a date, or head)"),
      svn_dirent_local_style(path_or_url, scratch_pool));
  return SVN_NO_ERROR;
}

/* Run a merge.
 *
 * (No docs yet, as this code was just hoisted out of svn_cl__merge().)
 *
 * Having FIRST_RANGE_START/_END params is ugly -- we should be able to use
 * PEG_REVISION1/2 and/or RANGES_TO_MERGE instead, maybe adjusting the caller.
 */
static svn_error_t *
run_merge(svn_boolean_t two_sources_specified,
          const char *sourcepath1,
          svn_opt_revision_t peg_revision1,
          const char *sourcepath2,
          const char *targetpath,
          apr_array_header_t *ranges_to_merge,
          svn_opt_revision_t first_range_start,
          svn_opt_revision_t first_range_end,
          svn_cl__opt_state_t *opt_state,
          apr_array_header_t *options,
          svn_client_ctx_t *ctx,
          apr_pool_t *scratch_pool)
{
  svn_error_t *merge_err;

  if (opt_state->reintegrate)
    {
      merge_err = svn_cl__deprecated_merge_reintegrate(
                    sourcepath1, &peg_revision1, targetpath,
                    opt_state->dry_run, options, ctx, scratch_pool);
    }
  else if (! two_sources_specified)
    {
      /* If we don't have at least one valid revision range, pick a
         good one that spans the entire set of revisions on our
         source. */
      if ((first_range_start.kind == svn_opt_revision_unspecified)
          && (first_range_end.kind == svn_opt_revision_unspecified))
        {
          ranges_to_merge = NULL;
        }

      if (opt_state->verbose)
        SVN_ERR(svn_cmdline_printf(scratch_pool, _("--- Merging\n")));
      merge_err = svn_client_merge_peg5(sourcepath1,
                                        ranges_to_merge,
                                        &peg_revision1,
                                        targetpath,
                                        opt_state->depth,
                                        opt_state->ignore_ancestry,
                                        opt_state->ignore_ancestry,
                                        opt_state->force, /* force_delete */
                                        opt_state->record_only,
                                        opt_state->dry_run,
                                        opt_state->allow_mixed_rev,
                                        options,
                                        ctx,
                                        scratch_pool);
    }
  else
    {
      if (svn_path_is_url(sourcepath1) != svn_path_is_url(sourcepath2))
        return svn_error_create(SVN_ERR_CL_ARG_PARSING_ERROR, NULL,
                                _("Merge sources must both be "
                                  "either paths or URLs"));

      if (svn_path_is_url(targetpath))
        return svn_error_createf(SVN_ERR_CL_ARG_PARSING_ERROR, NULL,
                                 _("Merge target '%s' must be a local path "
                                   "but looks like a URL"), targetpath);

      if (opt_state->verbose)
        SVN_ERR(svn_cmdline_printf(scratch_pool, _("--- Merging\n")));
      merge_err = svn_client_merge5(sourcepath1,
                                    &first_range_start,
                                    sourcepath2,
                                    &first_range_end,
                                    targetpath,
                                    opt_state->depth,
                                    opt_state->ignore_ancestry,
                                    opt_state->ignore_ancestry,
                                    opt_state->force, /* force_delete */
                                    opt_state->record_only,
                                    opt_state->dry_run,
                                    opt_state->allow_mixed_rev,
                                    options,
                                    ctx,
                                    scratch_pool);
    }

  return merge_err;
}

/* Baton type for conflict_func_merge_cmd(). */
struct conflict_func_merge_cmd_baton {
  svn_cl__accept_t accept_which;
  const char *path_prefix;
  svn_cl__conflict_stats_t *conflict_stats;
};

/* This implements the `svn_wc_conflict_resolver_func2_t ' interface.
 *
 * The merge subcommand needs to install this legacy conflict callback
 * in case the user passed an --accept option to 'svn merge'.
 * Otherwise, merges involving multiple editor drives might encounter a
 * conflict during one of the editor drives and abort with an error,
 * rather than resolving conflicts as per the --accept option and
 * continuing with the next editor drive.
 * ### TODO add an svn_client_merge API that makes this callback unnecessary
 */
static svn_error_t *
conflict_func_merge_cmd(svn_wc_conflict_result_t **result,
                        const svn_wc_conflict_description2_t *desc,
                        void *baton,
                        apr_pool_t *result_pool,
                        apr_pool_t *scratch_pool)
{
  struct conflict_func_merge_cmd_baton *b = baton;
  svn_wc_conflict_choice_t choice;

  switch (b->accept_which)
    {
    case svn_cl__accept_postpone:
    case svn_cl__accept_invalid:
    case svn_cl__accept_unspecified:
    case svn_cl__accept_recommended:
      /* Postpone or no valid --accept option, postpone the conflict. */
      choice = svn_wc_conflict_choose_postpone;
      break;
    case svn_cl__accept_base:
      choice = svn_wc_conflict_choose_base;
      break;
    case svn_cl__accept_working:
      choice = svn_wc_conflict_choose_merged;
      break;
    case svn_cl__accept_mine_conflict:
      choice = svn_wc_conflict_choose_mine_conflict;
      break;
    case svn_cl__accept_theirs_conflict:
      choice = svn_wc_conflict_choose_theirs_conflict;
      break;
    case svn_cl__accept_mine_full:
      choice = svn_wc_conflict_choose_mine_full;
      break;
    case svn_cl__accept_theirs_full:
      choice = svn_wc_conflict_choose_theirs_full;
      break;
    case svn_cl__accept_edit:
    case svn_cl__accept_launch:
      /* The 'edit' and 'launch' options used to be valid in Subversion 1.9 but
       * we can't support these options for the purposes of this callback. */
      choice = svn_wc_conflict_choose_postpone;
      break;
    }

  *result = svn_wc_create_conflict_result(choice, NULL, result_pool);

  /* If we are resolving a conflict, adjust the summary of conflicts. */
  if (choice != svn_wc_conflict_choose_postpone)
    {
      const char *local_path;

      local_path = svn_cl__local_style_skip_ancestor(b->path_prefix,
                                                     desc->local_abspath,
                                                     scratch_pool);
      svn_cl__conflict_stats_resolved(b->conflict_stats, local_path,
                                      desc->kind);
    }

  return SVN_NO_ERROR;
}

/* This implements the `svn_opt_subcommand_t' interface. */
svn_error_t *
svn_cl__merge(apr_getopt_t *os,
              void *baton,
              apr_pool_t *pool)
{
  svn_cl__opt_state_t *opt_state = ((svn_cl__cmd_baton_t *) baton)->opt_state;
  svn_cl__conflict_stats_t *conflict_stats =
    ((svn_cl__cmd_baton_t *) baton)->conflict_stats;
  svn_client_ctx_t *ctx = ((svn_cl__cmd_baton_t *) baton)->ctx;
  apr_array_header_t *targets;
  const char *sourcepath1 = NULL, *sourcepath2 = NULL, *targetpath = "";
  svn_boolean_t two_sources_specified = TRUE;
  svn_error_t *merge_err;
  svn_opt_revision_t first_range_start, first_range_end, peg_revision1,
    peg_revision2;
  apr_array_header_t *options, *ranges_to_merge = opt_state->revision_ranges;
  apr_array_header_t *conflicted_paths;
  svn_boolean_t has_explicit_target = FALSE;

  /* Merge doesn't support specifying a revision or revision range
     when using --reintegrate. */
  if (opt_state->reintegrate
      && opt_state->start_revision.kind != svn_opt_revision_unspecified)
    {
      return svn_error_create(SVN_ERR_CL_ARG_PARSING_ERROR, NULL,
                              _("-r and -c can't be used with --reintegrate"));
    }

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

  /* For now, we require at least one source.  That may change in
     future versions of Subversion, for example if we have support for
     negated mergeinfo.  See this IRC conversation:

       <bhuvan>   kfogel: yeah, i think you are correct; we should
                  specify the source url

       <kfogel>   bhuvan: I'll change the help output and propose for
                  backport.  Thanks.

       <bhuvan>   kfogel: np; while we are at it, 'svn merge' simply
                  returns nothing; i think we should say: """svn: Not
                  enough arguments provided; try 'svn help' for more
                  info"""

       <kfogel>   good idea

       <kfogel>   (in the future, 'svn merge' might actually do
                  something, but that's all the more reason to make
                  sure it errors now)

       <cmpilato> actually, i'm pretty sure 'svn merge' does something

       <cmpilato> it says "please merge any unmerged changes from
                  myself to myself."

       <cmpilato> :-)

       <kfogel>   har har

       <cmpilato> kfogel: i was serious.

       <kfogel>   cmpilato: urrr, uh.  Is that meaningful?  Is there
                  ever a reason for a user to run it?

       <cmpilato> kfogel: not while we don't have support for negated
                  mergeinfo.

       <kfogel>   cmpilato: do you concur that until it does something
                  useful it should error?

       <cmpilato> kfogel: yup.

       <kfogel>   cool
  */
  if (targets->nelts < 1)
    {
      return svn_error_create(SVN_ERR_CL_INSUFFICIENT_ARGS, 0,
                              _("Merge source required"));
    }
  else  /* Parse at least one, and possible two, sources. */
    {
      SVN_ERR(svn_opt_parse_path(&peg_revision1, &sourcepath1,
                                 APR_ARRAY_IDX(targets, 0, const char *),
                                 pool));
      if (targets->nelts >= 2)
        SVN_ERR(svn_opt_parse_path(&peg_revision2, &sourcepath2,
                                   APR_ARRAY_IDX(targets, 1, const char *),
                                   pool));
    }

  /* We could have one or two sources.  Deliberately written to stay
     correct even if we someday permit implied merge source. */
  if (targets->nelts <= 1)
    {
      two_sources_specified = FALSE;
    }
  else if (targets->nelts == 2)
    {
      if (svn_path_is_url(sourcepath1) && !svn_path_is_url(sourcepath2))
        two_sources_specified = FALSE;
    }

  if (opt_state->revision_ranges->nelts > 0)
    {
      first_range_start = APR_ARRAY_IDX(opt_state->revision_ranges, 0,
                                        svn_opt_revision_range_t *)->start;
      first_range_end = APR_ARRAY_IDX(opt_state->revision_ranges, 0,
                                      svn_opt_revision_range_t *)->end;
    }
  else
    {
      first_range_start.kind = first_range_end.kind =
        svn_opt_revision_unspecified;
    }

  /* If revision_ranges has at least one real range at this point, then
     we know the user must have used the '-r' and/or '-c' switch(es).
     This means we're *not* doing two distinct sources. */
  if (first_range_start.kind != svn_opt_revision_unspecified)
    {
      /* A revision *range* is required. */
      if (first_range_end.kind == svn_opt_revision_unspecified)
        return svn_error_create(SVN_ERR_CL_INSUFFICIENT_ARGS, 0,
                                _("Second revision required"));

      two_sources_specified = FALSE;
    }

  if (! two_sources_specified) /* TODO: Switch order of if */
    {
      if (targets->nelts > 2)
        return svn_error_create(SVN_ERR_CL_ARG_PARSING_ERROR, NULL,
                                _("Too many arguments given"));

      /* Set the default value for unspecified paths and peg revision. */
      /* targets->nelts is 1 ("svn merge SOURCE") or 2 ("svn merge
         SOURCE WCPATH") here. */
      sourcepath2 = sourcepath1;

      if (peg_revision1.kind == svn_opt_revision_unspecified)
        peg_revision1.kind = svn_path_is_url(sourcepath1)
          ? svn_opt_revision_head : svn_opt_revision_working;

      if (targets->nelts == 2)
        {
          targetpath = APR_ARRAY_IDX(targets, 1, const char *);
          has_explicit_target = TRUE;
          if (svn_path_is_url(targetpath))
            return svn_error_create(SVN_ERR_CL_ARG_PARSING_ERROR, NULL,
                                    _("Cannot specify a revision range "
                                      "with two URLs"));
        }
    }
  else /* using @rev syntax */
    {
      if (targets->nelts < 2)
        return svn_error_create(SVN_ERR_CL_INSUFFICIENT_ARGS, NULL, NULL);
      if (targets->nelts > 3)
        return svn_error_create(SVN_ERR_CL_ARG_PARSING_ERROR, NULL,
                                _("Too many arguments given"));

      first_range_start = peg_revision1;
      first_range_end = peg_revision2;

      /* Catch 'svn merge wc_path1 wc_path2 [target]' without explicit
         revisions--since it ignores local modifications it may not do what
         the user expects.  That is, it doesn't read from the WC itself, it
         reads from the WC's URL.  Forcing the user to specify a repository
         revision should avoid any confusion. */
      SVN_ERR(ensure_wc_path_has_repo_revision(sourcepath1, &first_range_start,
                                               pool));
      SVN_ERR(ensure_wc_path_has_repo_revision(sourcepath2, &first_range_end,
                                               pool));

      /* Default peg revisions to each URL's youngest revision. */
      if (first_range_start.kind == svn_opt_revision_unspecified)
        first_range_start.kind = svn_opt_revision_head;
      if (first_range_end.kind == svn_opt_revision_unspecified)
        first_range_end.kind = svn_opt_revision_head;

      /* Decide where to apply the delta (defaulting to "."). */
      if (targets->nelts == 3)
        {
          targetpath = APR_ARRAY_IDX(targets, 2, const char *);
          has_explicit_target = TRUE;
        }
    }

  /* If no targetpath was specified, see if we can infer it from the
     sourcepaths. */
  if (! has_explicit_target
      && sourcepath1 && sourcepath2
      && strcmp(targetpath, "") == 0)
    {
      /* If the sourcepath is a URL, it can only refer to a target in
         the current working directory or which is the current working
         directory.  However, if the sourcepath is a local path, it can
         refer to a target somewhere deeper in the directory structure. */
      if (svn_path_is_url(sourcepath1))
        {
          const char *sp1_basename = svn_uri_basename(sourcepath1, pool);
          const char *sp2_basename = svn_uri_basename(sourcepath2, pool);

          if (strcmp(sp1_basename, sp2_basename) == 0)
            {
              const char *target_url;
              const char *target_base;

              SVN_ERR(svn_client_url_from_path2(&target_url, targetpath, ctx,
                                                pool, pool));
              target_base = svn_uri_basename(target_url, pool);

              /* If the basename of the source is the same as the basename of
                 the cwd assume the cwd is the target. */
              if (strcmp(sp1_basename, target_base) != 0)
                {
                  svn_node_kind_t kind;

                  /* If the basename of the source differs from the basename
                     of the target.  We still might assume the cwd is the
                     target, but first check if there is a file in the cwd
                     with the same name as the source basename.  If there is,
                     then assume that file is the target. */
                  SVN_ERR(svn_io_check_path(sp1_basename, &kind, pool));
                  if (kind == svn_node_file)
                    {
                      targetpath = sp1_basename;
                    }
                }
            }
        }
      else if (strcmp(sourcepath1, sourcepath2) == 0)
        {
          svn_node_kind_t kind;

          SVN_ERR(svn_io_check_path(sourcepath1, &kind, pool));
          if (kind == svn_node_file)
            {
              targetpath = sourcepath1;
            }
        }
    }

  if (opt_state->extensions)
    options = svn_cstring_split(opt_state->extensions, " \t\n\r", TRUE, pool);
  else
    options = NULL;

  /* More input validation. */
  if (opt_state->reintegrate)
    {
      if (opt_state->ignore_ancestry)
        return svn_error_create(SVN_ERR_CL_MUTUALLY_EXCLUSIVE_ARGS, NULL,
                                _("--reintegrate cannot be used with "
                                  "--ignore-ancestry"));

      if (opt_state->record_only)
        return svn_error_create(SVN_ERR_CL_MUTUALLY_EXCLUSIVE_ARGS, NULL,
                                _("--reintegrate cannot be used with "
                                  "--record-only"));

      if (opt_state->depth != svn_depth_unknown)
        return svn_error_create(SVN_ERR_CL_MUTUALLY_EXCLUSIVE_ARGS, NULL,
                                _("--depth cannot be used with "
                                  "--reintegrate"));

      if (opt_state->force)
        return svn_error_create(SVN_ERR_CL_MUTUALLY_EXCLUSIVE_ARGS, NULL,
                                _("--force cannot be used with "
                                  "--reintegrate"));

      if (two_sources_specified)
        return svn_error_create(SVN_ERR_CL_ARG_PARSING_ERROR, NULL,
                                _("--reintegrate can only be used with "
                                  "a single merge source"));
      if (opt_state->allow_mixed_rev)
        return svn_error_create(SVN_ERR_CL_MUTUALLY_EXCLUSIVE_ARGS, NULL,
                                _("--allow-mixed-revisions cannot be used "
                                  "with --reintegrate"));
    }

  /* Install a legacy conflict handler if the --accept option was given.
   * Else, svn_client_merge5() may abort the merge in an undesirable way.
   * See the docstring at conflict_func_merge_cmd() for details */
  if (opt_state->accept_which != svn_cl__accept_unspecified)
    {
      struct conflict_func_merge_cmd_baton *b = apr_pcalloc(pool, sizeof(*b));

      b->accept_which = opt_state->accept_which;
      SVN_ERR(svn_dirent_get_absolute(&b->path_prefix, "", pool));
      b->conflict_stats = conflict_stats;

      ctx->conflict_func2 = conflict_func_merge_cmd;
      ctx->conflict_baton2 = b;
    }

retry:
  merge_err = run_merge(two_sources_specified,
                        sourcepath1, peg_revision1,
                        sourcepath2,
                        targetpath,
                        ranges_to_merge, first_range_start, first_range_end,
                        opt_state, options, ctx, pool);
  if (merge_err && merge_err->apr_err
                   == SVN_ERR_CLIENT_INVALID_MERGEINFO_NO_MERGETRACKING)
    {
      return svn_error_quick_wrap(
               merge_err,
               _("Merge tracking not possible, use --ignore-ancestry or\n"
                 "fix invalid mergeinfo in target with 'svn propset'"));
    }

  if (! opt_state->dry_run)
    {
      /* Run the interactive resolver if conflicts were raised. */
      SVN_ERR(svn_cl__conflict_stats_get_paths(&conflicted_paths,
                                               conflict_stats, pool, pool));
      if (conflicted_paths)
        {
          SVN_ERR(svn_cl__walk_conflicts(conflicted_paths, conflict_stats,
                                         opt_state, ctx, pool));
          if (merge_err && svn_error_root_cause(merge_err)->apr_err ==
              SVN_ERR_WC_FOUND_CONFLICT)
            {
              svn_error_t *err;

              /* Check if all conflicts were resolved just now. */
              err = svn_cl__conflict_stats_get_paths(&conflicted_paths,
                                                     conflict_stats,
                                                     pool, pool);
              if (err)
                merge_err = svn_error_compose_create(merge_err, err);
              else if (conflicted_paths == NULL)
                {
                  svn_error_clear(merge_err);
                  goto retry; /* ### conflicts resolved; continue merging */
                }
            }
        }
    }

  if (!opt_state->quiet)
    {
      svn_error_t *err = svn_cl__notifier_print_conflict_stats(
                           ctx->notify_baton2, pool);

      merge_err = svn_error_compose_create(merge_err, err);
    }

  return svn_cl__may_need_force(merge_err);
}
