/*
 * status.c: construct a status structure from an entry structure
 *
 * ====================================================================
 * Copyright (c) 2000-2002 CollabNet.  All rights reserved.
 *
 * This software is licensed as described in the file COPYING, which
 * you should have received as part of this distribution.  The terms
 * are also available at http://subversion.tigris.org/license-1.html.
 * If newer versions of this license are posted there, you may use a
 * newer version instead, at your option.
 *
 * This software consists of voluntary contributions made by many
 * individuals.  For exact contribution history, see the revision
 * history and logs, available at http://subversion.tigris.org/.
 * ====================================================================
 */



#include <string.h>
#include <apr_pools.h>
#include <apr_file_io.h>
#include <apr_hash.h>
#include <apr_time.h>
#include <apr_fnmatch.h>
#include "svn_pools.h"
#include "svn_types.h"
#include "svn_string.h"
#include "svn_error.h"
#include "svn_path.h"
#include "svn_wc.h"

#include "wc.h"
#include "props.h"


static void add_default_ignores (apr_array_header_t *patterns)
{
  static const char * const ignores[] = 
  {
    "*.o", "*.lo", "*.la", "#*#", "*.rej", "*~", ".#*",
    /* what else? */
    NULL
  };
  int i;
  
  for (i = 0; ignores[i] != NULL; i++)
    {
      const char **ent = apr_array_push(patterns);
      *ent = ignores[i];
    }

}


/* Helper routine: add to a *PATTERNS list patterns from the value of
   the SVN_PROP_IGNORE property set on DIRPATH.  If there is no such
   property, or the property contains no patterns, do nothing.
   Otherwise, add to *PATTERNS a list of (const char *) patterns to
   match. */
static svn_error_t *
add_ignore_patterns (const char *dirpath,
                     apr_array_header_t *patterns,
                     apr_pool_t *pool)
{
  const svn_string_t *value;

  /* Try to load the SVN_PROP_IGNORE property. */
  SVN_ERR (svn_wc_prop_get (&value, SVN_PROP_IGNORE, dirpath, pool));

  if (value != NULL)
    {
      static const char sep[3] = "\n\r";
      char *last;
      char *pats = apr_pstrdup (pool, value->data);
      char *p = apr_strtok (pats, sep, &last);

      while (p)
        {
          if (p[0] != '\0')
            {
              (*((const char **) apr_array_push (patterns))) = p;
            }
          p = apr_strtok (NULL, sep, &last);
        } 
    }    
  return SVN_NO_ERROR;
}                  


                        
/* Fill in *STATUS for PATH, whose entry data is in ENTRY.  Allocate
   *STATUS in POOL. 

   ENTRY may be null, for non-versioned entities.  In this case, we
   will assemble a special status structure item which implies a
   non-versioned thing.

   Else, ENTRY's pool must not be shorter-lived than STATUS's, since
   ENTRY will be stored directly, not copied.

   If GET_ALL is zero, and ENTRY is not locally modified, then *STATUS
   will be set to NULL.  If GET_ALL is non-zero, then *STATUS will be
   allocated and returned no matter what.

*/
static svn_error_t *
assemble_status (svn_wc_status_t **status,
                 svn_stringbuf_t *path,
                 svn_wc_entry_t *entry,
                 svn_boolean_t get_all,
                 svn_boolean_t strict,
                 apr_pool_t *pool)
{
  svn_wc_status_t *stat;
  enum svn_node_kind path_kind;
  svn_boolean_t has_props;
  svn_boolean_t text_modified_p = FALSE;
  svn_boolean_t prop_modified_p = FALSE;
  svn_boolean_t locked_p = FALSE;

  /* Defaults for two main variables. */
  enum svn_wc_status_kind final_text_status = svn_wc_status_normal;
  enum svn_wc_status_kind final_prop_status = svn_wc_status_none;

  /* Check the path kind for PATH. */
  SVN_ERR( svn_io_check_path (path->data, &path_kind, pool));

  if (! entry)
    {
      /* return a blank structure. */
      stat = apr_pcalloc (pool, sizeof(*stat));
      stat->entry = NULL;
      stat->text_status = svn_wc_status_none;
      stat->prop_status = svn_wc_status_none;
      stat->repos_text_status = svn_wc_status_none;
      stat->repos_prop_status = svn_wc_status_none;
      stat->locked = FALSE;
      stat->copied = FALSE;

      /* If this path has no entry, but IS present on disk, it's
         unversioned. */
      if (path_kind != svn_node_none)
        stat->text_status = svn_wc_status_unversioned;

      /* If we're in strict mode and we encounter a path that doesn't
         exist in the wc, then we return an error*/
      if (strict && (path_kind == svn_node_none))
        return svn_error_createf (APR_ENOENT, 0, NULL, pool,
                                  "assemble_status: "
                                  "%s: No such file or directory",
                                  path->data);

      *status = stat;
      return SVN_NO_ERROR;
    }

  /* Implement predecence rules: */

  /* 1. Set the two main variables to "discovered" values first (M, C). 
        Together, these two stati are of lowest precedence, and C has
        precedence over M. */

  /* Does the entry have props? */
  SVN_ERR (svn_wc__has_props (&has_props, path, pool));
  if (has_props)
    final_prop_status = svn_wc_status_normal;

  /* If the entry has a property file, see if it has local changes. */
  SVN_ERR (svn_wc_props_modified_p (&prop_modified_p, path, pool));
  
  /* If the entry is a file, check for textual modifications */
  if (entry->kind == svn_node_file)
    SVN_ERR (svn_wc_text_modified_p (&text_modified_p, path, pool));
  
  if (text_modified_p)
    final_text_status = svn_wc_status_modified;
  
  if (prop_modified_p)
    final_prop_status = svn_wc_status_modified;      
  
  if (entry->prejfile || entry->conflict_old || 
      entry->conflict_new || entry->conflict_wrk)
    {
      svn_boolean_t text_conflict_p, prop_conflict_p;
      svn_stringbuf_t *parent_dir;
      
      if (entry->kind == svn_node_dir)
        parent_dir = path;
      else  /* non-directory, that's all we need to know */
        {
          parent_dir = svn_stringbuf_dup (path, pool);
          svn_path_remove_component (parent_dir);
        }
      
      SVN_ERR (svn_wc_conflicted_p (&text_conflict_p, &prop_conflict_p,
                                    parent_dir, entry, pool));
      
      if (text_conflict_p)
        final_text_status = svn_wc_status_conflicted;
      if (prop_conflict_p)
        final_prop_status = svn_wc_status_conflicted;
    }
   
  /* 2. Possibly overwrite the the text_status variable with
        "scheduled" states from the entry (A, D, R).  As a group,
        these states are of medium precedence.  They also override any
        C or M that may be in the prop_status field at this point.*/

  if (entry->schedule == svn_wc_schedule_add)
    {
      final_text_status = svn_wc_status_added;
      final_prop_status = svn_wc_status_none;
    }
      
  else if (entry->schedule == svn_wc_schedule_replace)
    {
      final_text_status = svn_wc_status_replaced;
      final_prop_status = svn_wc_status_none;
    }
    
  else if (entry->schedule == svn_wc_schedule_delete)
    {
      final_text_status = svn_wc_status_deleted;
      final_prop_status = svn_wc_status_none;
    }


  /* 3. Highest precedence: check to see if file or dir is just
        missing.  This overrides every possible state *except*
        deletion.  (If something is deleted or scheduled for it, we
        don't care if the working file exists.)  */

  if ((path_kind == svn_node_none)
      && (final_text_status != svn_wc_status_deleted))
    final_text_status = svn_wc_status_absent;


  /* 4. Check for locked directory. */

  if (entry->kind == svn_node_dir)
    SVN_ERR (svn_wc_locked (&locked_p, path, pool));


  /* 5. Easy out:  unless we're fetching -every- entry, don't bother
     to allocate a struct for an uninteresting entry. */

  if (! get_all)
    if (((final_text_status == svn_wc_status_none)
         || (final_text_status == svn_wc_status_normal))
        && ((final_prop_status == svn_wc_status_none)
            || (final_prop_status == svn_wc_status_normal))
        && (! locked_p))
      {
        *status = NULL;
        return SVN_NO_ERROR;
      }


  /* 6. Build and return a status structure. */

  stat = apr_pcalloc (pool, sizeof(**status));
  stat->entry = svn_wc_entry_dup (entry, pool);
  stat->text_status = final_text_status;       
  stat->prop_status = final_prop_status;    
  stat->repos_text_status = svn_wc_status_none;   /* default */
  stat->repos_prop_status = svn_wc_status_none;   /* default */
  stat->locked = locked_p;
  stat->copied = entry->copied;

  *status = stat;

  return SVN_NO_ERROR;
}


/* Given an ENTRY object representing PATH, build a status structure
   and store it in STATUSHASH.  */
static svn_error_t *
add_status_structure (apr_hash_t *statushash,
                      svn_stringbuf_t *path,
                      svn_wc_entry_t *entry,
                      svn_boolean_t get_all,
                      svn_boolean_t strict,
                      apr_pool_t *pool)
{
  svn_wc_status_t *statstruct;
  
  SVN_ERR (assemble_status (&statstruct, path, entry, 
                            get_all, strict, pool));
  if (statstruct)
    apr_hash_set (statushash, path->data, path->len, statstruct);
  
  return SVN_NO_ERROR;
}


/* Add all items that are NOT in ENTRIES (which is a list of PATH's
   versioned things) to the STATUSHASH as unversioned items,
   allocating everything in POOL. */
static svn_error_t *
add_unversioned_items (svn_stringbuf_t *path, 
                       apr_hash_t *entries,
                       apr_hash_t *statushash,
                       apr_pool_t *pool)
{
  apr_pool_t *subpool = svn_pool_create (pool);
  apr_hash_t *dirents;
  apr_hash_index_t *hi;
  apr_array_header_t *patterns;

  /* Read PATH's dirents. */
  SVN_ERR (svn_io_get_dirents (&dirents, path, subpool));

  /* Try to load any '.svnignore' file that may be present. */
  patterns = apr_array_make (subpool, 1, sizeof(const char *));
  add_default_ignores (patterns);
  SVN_ERR (add_ignore_patterns (path->data, patterns, subpool));

  /* Add empty status structures for each of the unversioned things. */
  for (hi = apr_hash_first (subpool, dirents); hi; hi = apr_hash_next (hi))
    {
      const void *key;
      apr_ssize_t klen;
      void *val;
      const char *keystring;
      int i;
      int ignore_me;
      svn_stringbuf_t *printable_path;

      apr_hash_this (hi, &key, &klen, &val);
      keystring = (const char *) key;
        
      /* If the dirent isn't in `.svn/entries'... */
      if (apr_hash_get (entries, key, klen))        
        continue;

      /* and we're not looking at .svn... */
      if (! strcmp (keystring, SVN_WC_ADM_DIR_NAME))
        continue;

      ignore_me = 0;

      /* See if any of the ignore patterns we have matches our
         keystring. */
      for (i = 0; i < patterns->nelts; i++)
        {
          const char *pat = (((const char **) (patterns)->elts))[i];
                
          /* Try to match current_entry_name to pat. */
          if (APR_SUCCESS == apr_fnmatch (pat, keystring, FNM_PERIOD))
            {
              ignore_me = 1;
              break;
            }
        }
      
      /* If we aren't ignoring it, add a status structure for this
         dirent. */
      if (! ignore_me)
        {
          /* Reset our base string... */
          printable_path = svn_stringbuf_dup (path, pool);
          /* ...and append the current entry. */
          svn_path_add_component_nts (printable_path, keystring);
          
          /* Add this item to the status hash. */
          SVN_ERR (add_status_structure (statushash,
                                         printable_path,
                                         NULL, /* no entry */
                                         FALSE,
                                         FALSE,
                                         pool));
        }
    }

  svn_pool_destroy (subpool);

  return SVN_NO_ERROR;
}


svn_error_t *
svn_wc_status (svn_wc_status_t **status,
               svn_stringbuf_t *path,
               apr_pool_t *pool)
{
  svn_wc_status_t *s;
  svn_wc_entry_t *entry = NULL;

  /* Don't check for error;  PATH may be unversioned, or nonexistent
     (in the case of 'svn st -u' being told about as-yet-unknnown
     paths), and either condition will cause svn_wc_entry to return an
     error.  If this routine returns error, then a NULL entry will be
     passed to assemble_status() below, which is fine -- a blank
     status structure will be returned with either 'unversioned' or
     'absent' status filled in. */
  svn_wc_entry (&entry, path, pool);

  SVN_ERR (assemble_status (&s, path, entry, TRUE, FALSE, pool));
  *status = s;
  return SVN_NO_ERROR;
}



svn_error_t *
svn_wc_statuses (apr_hash_t *statushash,
                 svn_stringbuf_t *path,
                 svn_boolean_t descend,
                 svn_boolean_t get_all,
                 svn_boolean_t strict,
                 apr_pool_t *pool)
{
  enum svn_node_kind kind;
  svn_wc_entry_t *entry;

  /* Is PATH a directory or file? */
  SVN_ERR (svn_io_check_path (path->data, &kind, pool));
  
  /* kff todo: this has to deal with the case of a type-changing edit,
     i.e., someone removed a file under vc and replaced it with a dir,
     or vice versa.  In such a case, when you ask for the status, you
     should get mostly information about the now-vanished entity, plus
     some information about what happened to it.  The same situation
     is handled in entries.c:svn_wc_entry. */

  /* Read the appropriate entries file */
  
  /* If path points to just one file, or at least to just one
     non-directory, store just one status structure in the
     STATUSHASH and return. */
  if ((kind == svn_node_file) || (kind == svn_node_none))
    {
      /* Get the entry for this file. Place it into the specified pool since
         we're going to return it in statushash. */
      SVN_ERR (svn_wc_entry (&entry, path, pool));

      /* Convert the entry into a status structure, store in the hash.
         
         ### Notice that because we're getting one specific file,
         we're ignoring the GET_ALL flag and unconditionally fetching
         the status structure. */
      SVN_ERR (add_status_structure (statushash, path, entry, 
                                     TRUE, strict, pool));
    }


  /* Fill the hash with a status structure for *each* entry in PATH */
  else if (kind == svn_node_dir)
    {
      apr_hash_t *entries;
      apr_hash_index_t *hi;

      /* Load entries file for the directory into the requested pool. */
      SVN_ERR (svn_wc_entries_read (&entries, path, pool));

      /* Add the unversioned items to the status output. */
      SVN_ERR (add_unversioned_items (path, entries, statushash, pool));

      /* Loop over entries hash */
      for (hi = apr_hash_first (pool, entries); hi; hi = apr_hash_next (hi))
        {
          const void *key;
          void *val;
          const char *basename;
          apr_ssize_t keylen;

          /* Put fullpath into the request pool since it becomes a key
             in the output statushash hash table. */
          svn_stringbuf_t *fullpath = svn_stringbuf_dup (path, pool);

          /* Get the next dirent */
          apr_hash_this (hi, &key, &keylen, &val);
          basename = (const char *) key;
          if (strcmp (basename, SVN_WC_ENTRY_THIS_DIR) != 0)
            {
              svn_path_add_component_nts (fullpath, basename);
            }

          entry = (svn_wc_entry_t *) val;

          SVN_ERR (svn_io_check_path (fullpath->data, &kind, pool));

          /* In deciding whether or not to descend, we use the actual
             kind of the entity, not the kind claimed by the entries
             file.  The two are usually the same, but where they are
             not, its usually because some directory got moved, and
             one would still want a status report on its contents.
             kff todo: However, must handle mixed working copies.
             What if the subdir is not under revision control, or is
             from another repository? */
          
          /* Do *not* store THIS_DIR in the statushash, unless this
             path has never been seen before.  We don't want to add
             the path key twice. */
          if (! strcmp (basename, SVN_WC_ENTRY_THIS_DIR))
            {
              svn_wc_status_t *s = apr_hash_get (statushash,
                                                 fullpath->data,
                                                 fullpath->len);
              if (! s)
                SVN_ERR (add_status_structure (statushash, fullpath,
                                               entry, get_all, 
                                               strict, pool));
            }
          else
            {
              if (kind == svn_node_dir && descend)
                {
                  /* Directory entries are incomplete.  We must get
                     their full entry from their own THIS_DIR entry.
                     svn_wc_entry does this for us if it can.  */
                  svn_wc_entry_t *subdir;

                  SVN_ERR (svn_wc_entry (&subdir, fullpath, pool));
                  SVN_ERR (add_status_structure (statushash, fullpath,
                                                 subdir, get_all, 
                                                 strict, pool));
                  SVN_ERR (svn_wc_statuses (statushash, fullpath,
                                            descend, get_all, strict, pool)); 
                }
              else if ((kind == svn_node_file) || (kind == svn_node_none))
                {
                  /* File entries are ... just fine! */
                  SVN_ERR (add_status_structure (statushash, fullpath,
                                                 entry, get_all, 
                                                 strict, pool));
                }
            }
        }
    }
  
  return SVN_NO_ERROR;
}





/* 
 * local variables:
 * eval: (load-file "../../tools/dev/svn-dev.el")
 * end:
 */
