/*
 * questions.c:  routines for asking questions about working copies
 *
 * ====================================================================
 *    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.
 * ====================================================================
 */



#include <string.h>

#include <apr_pools.h>
#include <apr_file_io.h>
#include <apr_file_info.h>
#include <apr_time.h>

#include "svn_pools.h"
#include "svn_types.h"
#include "svn_string.h"
#include "svn_error.h"
#include "svn_dirent_uri.h"
#include "svn_time.h"
#include "svn_io.h"
#include "svn_props.h"

#include "wc.h"
#include "conflicts.h"
#include "translate.h"
#include "wc_db.h"

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



/*** svn_wc_text_modified_p ***/

/* svn_wc_text_modified_p answers the question:

   "Are the contents of F different than the contents of
   .svn/text-base/F.svn-base or .svn/tmp/text-base/F.svn-base?"

   In the first case, we're looking to see if a user has made local
   modifications to a file since the last update or commit.  In the
   second, the file may not be versioned yet (it doesn't exist in
   entries).  Support for the latter case came about to facilitate
   forced checkouts, updates, and switches, where an unversioned file
   may obstruct a file about to be added.

   Note: Assuming that F lives in a directory D at revision V, please
   notice that we are *NOT* answering the question, "are the contents
   of F different than revision V of F?"  While F may be at a different
   revision number than its parent directory, but we're only looking
   for local edits on F, not for consistent directory revisions.

   TODO:  the logic of the routines on this page might change in the
   future, as they bear some relation to the user interface.  For
   example, if a file is removed -- without telling subversion about
   it -- how should subversion react?  Should it copy the file back
   out of text-base?  Should it ask whether one meant to officially
   mark it for removal?
*/


/* Set *MODIFIED_P to TRUE if (after translation) VERSIONED_FILE_ABSPATH
 * (of VERSIONED_FILE_SIZE bytes) differs from PRISTINE_STREAM (of
 * PRISTINE_SIZE bytes), else to FALSE if not.
 *
 * If EXACT_COMPARISON is FALSE, translate VERSIONED_FILE_ABSPATH's EOL
 * style and keywords to repository-normal form according to its properties,
 * and compare the result with PRISTINE_STREAM.  If EXACT_COMPARISON is
 * TRUE, translate PRISTINE_STREAM's EOL style and keywords to working-copy
 * form according to VERSIONED_FILE_ABSPATH's properties, and compare the
 * result with VERSIONED_FILE_ABSPATH.
 *
 * HAS_PROPS should be TRUE if the file had properties when it was not
 * modified, otherwise FALSE.
 *
 * PROPS_MOD should be TRUE if the file's properties have been changed,
 * otherwise FALSE.
 *
 * PRISTINE_STREAM will be closed before a successful return.
 *
 * DB is a wc_db; use SCRATCH_POOL for temporary allocation.
 */
static svn_error_t *
compare_and_verify(svn_boolean_t *modified_p,
                   svn_wc__db_t *db,
                   const char *versioned_file_abspath,
                   svn_filesize_t versioned_file_size,
                   svn_stream_t *pristine_stream,
                   svn_filesize_t pristine_size,
                   svn_boolean_t has_props,
                   svn_boolean_t props_mod,
                   svn_boolean_t exact_comparison,
                   apr_pool_t *scratch_pool)
{
  svn_boolean_t same;
  svn_subst_eol_style_t eol_style;
  const char *eol_str;
  apr_hash_t *keywords;
  svn_boolean_t special = FALSE;
  svn_boolean_t need_translation;
  svn_stream_t *v_stream; /* versioned_file */

  SVN_ERR_ASSERT(svn_dirent_is_absolute(versioned_file_abspath));

  if (props_mod)
    has_props = TRUE; /* Maybe it didn't have properties; but it has now */

  if (has_props)
    {
      SVN_ERR(svn_wc__get_translate_info(&eol_style, &eol_str,
                                         &keywords,
                                         &special,
                                         db, versioned_file_abspath, NULL,
                                         !exact_comparison,
                                         scratch_pool, scratch_pool));

      need_translation = svn_subst_translation_required(eol_style, eol_str,
                                                        keywords, special,
                                                        TRUE);
    }
  else
    need_translation = FALSE;

  if (! need_translation
      && (versioned_file_size != pristine_size))
    {
      *modified_p = TRUE;

      /* ### Why did we open the pristine? */
      return svn_error_trace(svn_stream_close(pristine_stream));
    }

  /* ### Other checks possible? */

  /* Reading files is necessary. */
  if (special && need_translation)
    {
      SVN_ERR(svn_subst_read_specialfile(&v_stream, versioned_file_abspath,
                                          scratch_pool, scratch_pool));
    }
  else
    {
      /* We don't use APR-level buffering because the comparison function
       * will do its own buffering. */
      apr_file_t *file;
      SVN_ERR(svn_io_file_open(&file, versioned_file_abspath, APR_READ,
                               APR_OS_DEFAULT, scratch_pool));
      v_stream = svn_stream_from_aprfile2(file, FALSE, scratch_pool);

      if (need_translation)
        {
          if (!exact_comparison)
            {
              if (eol_style == svn_subst_eol_style_native)
                eol_str = SVN_SUBST_NATIVE_EOL_STR;
              else if (eol_style != svn_subst_eol_style_fixed
                       && eol_style != svn_subst_eol_style_none)
                return svn_error_create(SVN_ERR_IO_UNKNOWN_EOL,
                                        svn_stream_close(v_stream), NULL);

              /* Wrap file stream to detranslate into normal form,
               * "repairing" the EOL style if it is inconsistent. */
              v_stream = svn_subst_stream_translated(v_stream,
                                                     eol_str,
                                                     TRUE /* repair */,
                                                     keywords,
                                                     FALSE /* expand */,
                                                     scratch_pool);
            }
          else
            {
              /* Wrap base stream to translate into working copy form, and
               * arrange to throw an error if its EOL style is inconsistent. */
              pristine_stream = svn_subst_stream_translated(pristine_stream,
                                                            eol_str, FALSE,
                                                            keywords, TRUE,
                                                            scratch_pool);
            }
        }
    }

  SVN_ERR(svn_stream_contents_same2(&same, pristine_stream, v_stream,
                                    scratch_pool));

  *modified_p = (! same);

  return SVN_NO_ERROR;
}

svn_error_t *
svn_wc__internal_file_modified_p(svn_boolean_t *modified_p,
                                 svn_wc__db_t *db,
                                 const char *local_abspath,
                                 svn_boolean_t exact_comparison,
                                 apr_pool_t *scratch_pool)
{
  svn_stream_t *pristine_stream;
  svn_filesize_t pristine_size;
  svn_wc__db_status_t status;
  svn_node_kind_t kind;
  const svn_checksum_t *checksum;
  svn_filesize_t recorded_size;
  apr_time_t recorded_mod_time;
  svn_boolean_t has_props;
  svn_boolean_t props_mod;
  const svn_io_dirent2_t *dirent;

  /* Read the relevant info */
  SVN_ERR(svn_wc__db_read_info(&status, &kind, NULL, NULL, NULL, NULL, NULL,
                               NULL, NULL, NULL, &checksum, NULL, NULL, NULL,
                               NULL, NULL, NULL,
                               &recorded_size, &recorded_mod_time,
                               NULL, NULL, NULL, &has_props, &props_mod,
                               NULL, NULL, NULL,
                               db, local_abspath,
                               scratch_pool, scratch_pool));

  /* If we don't have a pristine or the node has a status that allows a
     pristine, just say that the node is modified */
  if (!checksum
      || (kind != svn_node_file)
      || ((status != svn_wc__db_status_normal)
          && (status != svn_wc__db_status_added)))
    {
      *modified_p = TRUE;
      return SVN_NO_ERROR;
    }

  SVN_ERR(svn_io_stat_dirent2(&dirent, local_abspath, FALSE, TRUE,
                              scratch_pool, scratch_pool));

  if (dirent->kind != svn_node_file)
    {
      /* There is no file on disk, so the text is missing, not modified. */
      *modified_p = FALSE;
      return SVN_NO_ERROR;
    }

  if (! exact_comparison)
    {
      /* We're allowed to use a heuristic to determine whether files may
         have changed.  The heuristic has these steps:

         1. Compare the working file's size
            with the size cached in the entries file
         2. If they differ, do a full file compare
         3. Compare the working file's timestamp
            with the timestamp cached in the entries file
         4. If they differ, do a full file compare
         5. Otherwise, return indicating an unchanged file.

         There are 2 problematic situations which may occur:

         1. The cached working size is missing
         --> In this case, we forget we ever tried to compare
             and skip to the timestamp comparison.  This is
             because old working copies do not contain cached sizes

         2. The cached timestamp is missing
         --> In this case, we forget we ever tried to compare
             and skip to full file comparison.  This is because
             the timestamp will be removed when the library
             updates a locally changed file.  (ie, this only happens
             when the file was locally modified.)

      */

      /* Compare the sizes, if applicable */
      if (recorded_size != SVN_INVALID_FILESIZE
          && dirent->filesize != recorded_size)
        goto compare_them;

      /* Compare the timestamps

         Note: recorded_mod_time == 0 means not available,
               which also means the timestamps won't be equal,
               so there's no need to explicitly check the 'absent' value. */
      if (recorded_mod_time != dirent->mtime)
        goto compare_them;

      *modified_p = FALSE;
      return SVN_NO_ERROR;
    }

 compare_them:
  SVN_ERR(svn_wc__db_pristine_read(&pristine_stream, &pristine_size,
                                   db, local_abspath, checksum,
                                   scratch_pool, scratch_pool));

  /* Check all bytes, and verify checksum if requested. */
  {
    svn_error_t *err;
    err = compare_and_verify(modified_p, db,
                             local_abspath, dirent->filesize,
                             pristine_stream, pristine_size,
                             has_props, props_mod,
                             exact_comparison,
                             scratch_pool);

    /* At this point we already opened the pristine file, so we know that
       the access denied applies to the working copy path */
    if (err && APR_STATUS_IS_EACCES(err->apr_err))
      return svn_error_create(SVN_ERR_WC_PATH_ACCESS_DENIED, err, NULL);
    else
      SVN_ERR(err);
  }

  if (!*modified_p)
    {
      svn_boolean_t own_lock;

      /* The timestamp is missing or "broken" so "repair" it if we can. */
      SVN_ERR(svn_wc__db_wclock_owns_lock(&own_lock, db, local_abspath, FALSE,
                                          scratch_pool));
      if (own_lock)
        SVN_ERR(svn_wc__db_global_record_fileinfo(db, local_abspath,
                                                  dirent->filesize,
                                                  dirent->mtime,
                                                  scratch_pool));
    }

  return SVN_NO_ERROR;
}


svn_error_t *
svn_wc_text_modified_p2(svn_boolean_t *modified_p,
                        svn_wc_context_t *wc_ctx,
                        const char *local_abspath,
                        svn_boolean_t unused,
                        apr_pool_t *scratch_pool)
{
  return svn_wc__internal_file_modified_p(modified_p, wc_ctx->db,
                                          local_abspath, FALSE, scratch_pool);
}



static svn_error_t *
internal_conflicted_p(svn_boolean_t *text_conflicted_p,
                      svn_boolean_t *prop_conflicted_p,
                      svn_boolean_t *tree_conflicted_p,
                      svn_boolean_t *ignore_move_edit_p,
                      svn_wc__db_t *db,
                      const char *local_abspath,
                      apr_pool_t *scratch_pool)
{
  svn_node_kind_t kind;
  svn_skel_t *conflicts;
  svn_boolean_t resolved_text = FALSE;
  svn_boolean_t resolved_props = FALSE;

  SVN_ERR(svn_wc__db_read_conflict(&conflicts, NULL, NULL,
                                   db, local_abspath,
                                   scratch_pool, scratch_pool));

  if (!conflicts)
    {
      if (text_conflicted_p)
        *text_conflicted_p = FALSE;
      if (prop_conflicted_p)
        *prop_conflicted_p = FALSE;
      if (tree_conflicted_p)
        *tree_conflicted_p = FALSE;
      if (ignore_move_edit_p)
        *ignore_move_edit_p = FALSE;

      return SVN_NO_ERROR;
    }

  SVN_ERR(svn_wc__conflict_read_info(NULL, NULL, text_conflicted_p,
                                     prop_conflicted_p, tree_conflicted_p,
                                     db, local_abspath, conflicts,
                                     scratch_pool, scratch_pool));

  if (text_conflicted_p && *text_conflicted_p)
    {
      const char *mine_abspath;
      const char *their_old_abspath;
      const char *their_abspath;
      svn_boolean_t done = FALSE;

      /* Look for any text conflict, exercising only as much effort as
         necessary to obtain a definitive answer.  This only applies to
         files, but we don't have to explicitly check that entry is a
         file, since these attributes would never be set on a directory
         anyway.  A conflict file entry notation only counts if the
         conflict file still exists on disk.  */

      SVN_ERR(svn_wc__conflict_read_text_conflict(&mine_abspath,
                                                  &their_old_abspath,
                                                  &their_abspath,
                                                  db, local_abspath, conflicts,
                                                  scratch_pool, scratch_pool));

      if (mine_abspath)
        {
          SVN_ERR(svn_io_check_path(mine_abspath, &kind, scratch_pool));

          *text_conflicted_p = (kind == svn_node_file);

          if (*text_conflicted_p)
            done = TRUE;
        }

      if (!done && their_abspath)
        {
          SVN_ERR(svn_io_check_path(their_abspath, &kind, scratch_pool));

          *text_conflicted_p = (kind == svn_node_file);

          if (*text_conflicted_p)
            done = TRUE;
        }

        if (!done && their_old_abspath)
        {
          SVN_ERR(svn_io_check_path(their_old_abspath, &kind, scratch_pool));

          *text_conflicted_p = (kind == svn_node_file);

          if (*text_conflicted_p)
            done = TRUE;
        }

        if (!done && (mine_abspath || their_abspath || their_old_abspath))
          resolved_text = TRUE; /* Remove in-db conflict marker */
    }

  if (prop_conflicted_p && *prop_conflicted_p)
    {
      const char *prej_abspath;

      SVN_ERR(svn_wc__conflict_read_prop_conflict(&prej_abspath,
                                                  NULL, NULL, NULL, NULL,
                                                  db, local_abspath, conflicts,
                                                  scratch_pool, scratch_pool));

      if (prej_abspath)
        {
          SVN_ERR(svn_io_check_path(prej_abspath, &kind, scratch_pool));

          *prop_conflicted_p = (kind == svn_node_file);

          if (! *prop_conflicted_p)
            resolved_props = TRUE; /* Remove in-db conflict marker */
        }
    }

  if (ignore_move_edit_p)
    {
      *ignore_move_edit_p = FALSE;
      if (tree_conflicted_p && *tree_conflicted_p)
        {
          svn_wc_conflict_reason_t reason;
          svn_wc_conflict_action_t action;

          SVN_ERR(svn_wc__conflict_read_tree_conflict(&reason, &action, NULL,
                                                      NULL, db, local_abspath,
                                                      conflicts,
                                                      scratch_pool,
                                                      scratch_pool));

          if (reason == svn_wc_conflict_reason_moved_away
              && action == svn_wc_conflict_action_edit)
            {
              *tree_conflicted_p = FALSE;
              *ignore_move_edit_p = TRUE;
            }
        }
    }

  if (resolved_text || resolved_props)
    {
      svn_boolean_t own_lock;

      /* The marker files are missing, so "repair" wc.db if we can */
      SVN_ERR(svn_wc__db_wclock_owns_lock(&own_lock, db, local_abspath, FALSE,
                                          scratch_pool));
      if (own_lock)
        SVN_ERR(svn_wc__db_op_mark_resolved(db, local_abspath,
                                            resolved_text,
                                            resolved_props,
                                            FALSE /* resolved_tree */,
                                            NULL /* work_items */,
                                            scratch_pool));
    }

  return SVN_NO_ERROR;
}

svn_error_t *
svn_wc__internal_conflicted_p(svn_boolean_t *text_conflicted_p,
                              svn_boolean_t *prop_conflicted_p,
                              svn_boolean_t *tree_conflicted_p,
                              svn_wc__db_t *db,
                              const char *local_abspath,
                              apr_pool_t *scratch_pool)
{
  SVN_ERR(internal_conflicted_p(text_conflicted_p, prop_conflicted_p,
                                tree_conflicted_p, NULL,
                                db, local_abspath, scratch_pool));
  return SVN_NO_ERROR;
}

svn_error_t *
svn_wc__conflicted_for_update_p(svn_boolean_t *conflicted_p,
                                svn_boolean_t *conflict_ignored_p,
                                svn_wc__db_t *db,
                                const char *local_abspath,
                                svn_boolean_t tree_only,
                                apr_pool_t *scratch_pool)
{
  svn_boolean_t text_conflicted, prop_conflicted, tree_conflicted;
  svn_boolean_t conflict_ignored;

  if (!conflict_ignored_p)
    conflict_ignored_p = &conflict_ignored;

  SVN_ERR(internal_conflicted_p(tree_only ? NULL: &text_conflicted,
                                tree_only ? NULL: &prop_conflicted,
                                &tree_conflicted, conflict_ignored_p,
                                db, local_abspath, scratch_pool));
  if (tree_only)
    *conflicted_p = tree_conflicted;
  else
    *conflicted_p = text_conflicted || prop_conflicted || tree_conflicted;

  return SVN_NO_ERROR;
}


svn_error_t *
svn_wc_conflicted_p3(svn_boolean_t *text_conflicted_p,
                     svn_boolean_t *prop_conflicted_p,
                     svn_boolean_t *tree_conflicted_p,
                     svn_wc_context_t *wc_ctx,
                     const char *local_abspath,
                     apr_pool_t *scratch_pool)
{
  return svn_error_trace(svn_wc__internal_conflicted_p(text_conflicted_p,
                                                       prop_conflicted_p,
                                                       tree_conflicted_p,
                                                       wc_ctx->db,
                                                       local_abspath,
                                                       scratch_pool));
}

svn_error_t *
svn_wc__min_max_revisions(svn_revnum_t *min_revision,
                          svn_revnum_t *max_revision,
                          svn_wc_context_t *wc_ctx,
                          const char *local_abspath,
                          svn_boolean_t committed,
                          apr_pool_t *scratch_pool)
{
  return svn_error_trace(svn_wc__db_min_max_revisions(min_revision,
                                                      max_revision,
                                                      wc_ctx->db,
                                                      local_abspath,
                                                      committed,
                                                      scratch_pool));
}


svn_error_t *
svn_wc__has_switched_subtrees(svn_boolean_t *is_switched,
                              svn_wc_context_t *wc_ctx,
                              const char *local_abspath,
                              const char *trail_url,
                              apr_pool_t *scratch_pool)
{
  return svn_error_trace(svn_wc__db_has_switched_subtrees(is_switched,
                                                          wc_ctx->db,
                                                          local_abspath,
                                                          trail_url,
                                                          scratch_pool));
}


/* A baton for use with modcheck_found_entry(). */
typedef struct modcheck_baton_t {
  svn_boolean_t ignore_unversioned;
  svn_boolean_t found_mod;  /* whether a modification has been found */
  svn_boolean_t found_not_delete;  /* Found a not-delete modification */
} modcheck_baton_t;

/* An implementation of svn_wc_status_func4_t. */
static svn_error_t *
modcheck_callback(void *baton,
                  const char *local_abspath,
                  const svn_wc_status3_t *status,
                  apr_pool_t *scratch_pool)
{
  modcheck_baton_t *mb = baton;

  switch (status->node_status)
    {
      case svn_wc_status_normal:
      case svn_wc_status_ignored:
      case svn_wc_status_none:
      case svn_wc_status_external:
        break;

      case svn_wc_status_incomplete:
        if ((status->text_status != svn_wc_status_normal
             && status->text_status != svn_wc_status_none)
            || (status->prop_status != svn_wc_status_normal
                && status->prop_status != svn_wc_status_none))
          {
            mb->found_mod = TRUE;
            mb->found_not_delete = TRUE;
            /* Incomplete, but local modifications */
            return svn_error_create(SVN_ERR_CEASE_INVOCATION, NULL, NULL);
          }
        break;

      case svn_wc_status_deleted:
        mb->found_mod = TRUE;
        if (!mb->ignore_unversioned
            && status->actual_kind != svn_node_none
            && status->actual_kind != svn_node_unknown)
          {
            /* The delete is obstructed by something unversioned */
            mb->found_not_delete = TRUE;
            return svn_error_create(SVN_ERR_CEASE_INVOCATION, NULL, NULL);
          }
        break;

      case svn_wc_status_unversioned:
        if (mb->ignore_unversioned)
          break;
        /* else fall through */
      case svn_wc_status_missing:
      case svn_wc_status_obstructed:
        mb->found_mod = TRUE;
        mb->found_not_delete = TRUE;
        /* Exit from the status walker: We know what we want to know */
        return svn_error_create(SVN_ERR_CEASE_INVOCATION, NULL, NULL);

      default:
      case svn_wc_status_added:
      case svn_wc_status_replaced:
      case svn_wc_status_modified:
        mb->found_mod = TRUE;
        mb->found_not_delete = TRUE;
        /* Exit from the status walker: We know what we want to know */
        return svn_error_create(SVN_ERR_CEASE_INVOCATION, NULL, NULL);
    }

  return SVN_NO_ERROR;
}


/* Set *MODIFIED to true iff there are any local modifications within the
 * tree rooted at LOCAL_ABSPATH, using DB. If *MODIFIED
 * is set to true and all the local modifications were deletes then set
 * *ALL_EDITS_ARE_DELETES to true, set it to false otherwise.  LOCAL_ABSPATH
 * may be a file or a directory. */
svn_error_t *
svn_wc__node_has_local_mods(svn_boolean_t *modified,
                            svn_boolean_t *all_edits_are_deletes,
                            svn_wc__db_t *db,
                            const char *local_abspath,
                            svn_boolean_t ignore_unversioned,
                            svn_cancel_func_t cancel_func,
                            void *cancel_baton,
                            apr_pool_t *scratch_pool)
{
  modcheck_baton_t modcheck_baton = { FALSE, FALSE, FALSE };
  svn_error_t *err;

  if (!all_edits_are_deletes)
    {
      SVN_ERR(svn_wc__db_has_db_mods(modified, db, local_abspath,
                                     scratch_pool));

      if (*modified)
        return SVN_NO_ERROR;
    }

  modcheck_baton.ignore_unversioned = ignore_unversioned;

  /* Walk the WC tree for status with depth infinity, looking for any local
   * modifications. If it's a "sparse" directory, that's OK: there can be
   * no local mods in the pieces that aren't present in the WC. */

  err = svn_wc__internal_walk_status(db, local_abspath,
                                     svn_depth_infinity,
                                     FALSE, FALSE, FALSE, NULL,
                                     modcheck_callback, &modcheck_baton,
                                     cancel_func, cancel_baton,
                                     scratch_pool);

  if (err && err->apr_err == SVN_ERR_CEASE_INVOCATION)
    svn_error_clear(err);
  else
    SVN_ERR(err);

  *modified = modcheck_baton.found_mod;
  if (all_edits_are_deletes)
    *all_edits_are_deletes = (modcheck_baton.found_mod
                              && !modcheck_baton.found_not_delete);

  return SVN_NO_ERROR;
}

svn_error_t *
svn_wc__has_local_mods(svn_boolean_t *is_modified,
                       svn_wc_context_t *wc_ctx,
                       const char *local_abspath,
                       svn_boolean_t ignore_unversioned,
                       svn_cancel_func_t cancel_func,
                       void *cancel_baton,
                       apr_pool_t *scratch_pool)
{
  svn_boolean_t modified;

  SVN_ERR(svn_wc__node_has_local_mods(&modified, NULL,
                                      wc_ctx->db, local_abspath,
                                      ignore_unversioned,
                                      cancel_func, cancel_baton,
                                      scratch_pool));

  *is_modified = modified;
  return SVN_NO_ERROR;
}
