/*
 * config_file.c :  efficiently read config files from disk or repo
 *
 * ====================================================================
 *    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 "svn_checksum.h"
#include "svn_path.h"
#include "svn_pools.h"

#include "private/svn_subr_private.h"
#include "private/svn_repos_private.h"
#include "private/svn_config_private.h"

#include "config_file.h"

#include "svn_private_config.h"



struct config_access_t
{
  /* The last repository that we found the requested URL in.  May be NULL. */
  svn_repos_t *repos;

  /* Owning pool of this structure and is private to this structure.
   * All objects with the lifetime of this access object will be allocated
   * from this pool. */
  apr_pool_t *pool;
};



/* A stream object that gives access to a representation's content but
 * delays accessing the repository data until the stream is first used.
 * IOW, the stream object is cheap as long as it is not accessed.
 */
typedef struct presentation_stream_baton_t
{
  svn_fs_root_t *root;
  const char *fs_path;
  apr_pool_t *pool;
  svn_stream_t *inner;
} presentation_stream_baton_t;

static svn_error_t *
auto_open_inner_stream(presentation_stream_baton_t *b)
{
  if (!b->inner)
    {
      svn_filesize_t length;
      svn_stream_t *stream;
      svn_stringbuf_t *contents;

      SVN_ERR(svn_fs_file_length(&length, b->root, b->fs_path, b->pool));
      SVN_ERR(svn_fs_file_contents(&stream, b->root, b->fs_path, b->pool));
      SVN_ERR(svn_stringbuf_from_stream(&contents, stream,
                                        (apr_size_t)length, b->pool));
      b->inner = svn_stream_from_stringbuf(contents, b->pool);
    }

  return SVN_NO_ERROR;
}

static svn_error_t *
read_handler_rep(void *baton, char *buffer, apr_size_t *len)
{
  presentation_stream_baton_t *b = baton;
  SVN_ERR(auto_open_inner_stream(b));

  return svn_error_trace(svn_stream_read2(b->inner, buffer, len));
}

static svn_error_t *
mark_handler_rep(void *baton, svn_stream_mark_t **mark, apr_pool_t *pool)
{
  presentation_stream_baton_t *b = baton;
  SVN_ERR(auto_open_inner_stream(b));

  return svn_error_trace(svn_stream_mark(b->inner, mark, pool));
}

static svn_error_t *
seek_handler_rep(void *baton, const svn_stream_mark_t *mark)
{
  presentation_stream_baton_t *b = baton;
  SVN_ERR(auto_open_inner_stream(b));

  return svn_error_trace(svn_stream_seek(b->inner, mark));
}

static svn_error_t *
skip_handler_rep(void *baton, apr_size_t len)
{
  presentation_stream_baton_t *b = baton;
  SVN_ERR(auto_open_inner_stream(b));

  return svn_error_trace(svn_stream_skip(b->inner, len));
}

static svn_error_t *
data_available_handler_rep(void *baton, svn_boolean_t *data_available)
{
  presentation_stream_baton_t *b = baton;
  SVN_ERR(auto_open_inner_stream(b));

  return svn_error_trace(svn_stream_data_available(b->inner, data_available));
}

static svn_error_t *
readline_handler_rep(void *baton,
                        svn_stringbuf_t **stringbuf,
                        const char *eol,
                        svn_boolean_t *eof,
                        apr_pool_t *pool)
{
  presentation_stream_baton_t *b = baton;
  SVN_ERR(auto_open_inner_stream(b));

  return svn_error_trace(svn_stream_readline(b->inner, stringbuf, eol, eof,
                                             pool));
}

/* Return a lazy access stream for FS_PATH under ROOT, allocated in POOL. */
static svn_stream_t *
representation_stream(svn_fs_root_t *root,
                      const char *fs_path,
                      apr_pool_t *pool)
{
  svn_stream_t *stream;
  presentation_stream_baton_t *baton;

  baton = apr_pcalloc(pool, sizeof(*baton));
  baton->root = root;
  baton->fs_path = fs_path;
  baton->pool = pool;

  stream = svn_stream_create(baton, pool);
  svn_stream_set_read2(stream, read_handler_rep, read_handler_rep);
  svn_stream_set_mark(stream, mark_handler_rep);
  svn_stream_set_seek(stream, seek_handler_rep);
  svn_stream_set_skip(stream, skip_handler_rep);
  svn_stream_set_data_available(stream, data_available_handler_rep);
  svn_stream_set_readline(stream, readline_handler_rep);
  return stream;
}

/* Handle the case of a file PATH / url pointing to anything that is either
 * not a file or does not exist at all.   The case is given by NODE_KIND.
 *
 * If MUST_EXIST is not set and the file does not exist at all, return a
 * default *STREAM and *CHECKSUM allocated in the context of ACCESS, or an
 * error otherwise.
 */
static svn_error_t *
handle_missing_file(svn_stream_t **stream,
                    svn_checksum_t **checksum,
                    config_access_t *access,
                    const char *path,
                    svn_boolean_t must_exist,
                    svn_node_kind_t node_kind)
{
  if (node_kind == svn_node_none && !must_exist)
    {
      *stream = svn_stream_empty(access->pool);
      SVN_ERR(svn_checksum(checksum, svn_checksum_md5, "", 0, access->pool));
    }
  else if (node_kind != svn_node_file)
    {
      return svn_error_createf(SVN_ERR_ILLEGAL_TARGET, NULL,
                               "'%s' is not a file", path);
    }

  return SVN_NO_ERROR;
}

/* Open the in-repository file at URL, return its content checksum in
 * *CHECKSUM and the content itself through *STREAM.  Allocate those with
 * the lifetime of ACCESS and use SCRATCH_POOL for temporaries.
 *
 * Error out when the file does not exist but MUST_EXIST is set.
 */
static svn_error_t *
get_repos_config(svn_stream_t **stream,
                 svn_checksum_t **checksum,
                 config_access_t *access,
                 const char *url,
                 svn_boolean_t must_exist,
                 apr_pool_t *scratch_pool)
{
  svn_fs_t *fs;
  svn_fs_root_t *root;
  svn_revnum_t youngest_rev;
  svn_node_kind_t node_kind;
  const char *dirent;
  const char *fs_path;
  const char *repos_root_dirent;

  SVN_ERR(svn_uri_get_dirent_from_file_url(&dirent, url, access->pool));

  /* Maybe we can use the repos hint instance instead of creating a
   * new one. */
  if (access->repos)
    {
      repos_root_dirent = svn_repos_path(access->repos, scratch_pool);
      if (!svn_dirent_is_absolute(repos_root_dirent))
        SVN_ERR(svn_dirent_get_absolute(&repos_root_dirent,
                                        repos_root_dirent,
                                        scratch_pool));

      if (!svn_dirent_is_ancestor(repos_root_dirent, dirent))
        access->repos = NULL;
    }

  /* Open repos if no suitable repos is available. */
  if (!access->repos)
    {
      /* Search for a repository in the full path. */
      repos_root_dirent = svn_repos_find_root_path(dirent, scratch_pool);
      if (repos_root_dirent == NULL)
        return svn_error_trace(handle_missing_file(stream, checksum, access,
                                                   url, must_exist,
                                                   svn_node_none));

      /* Attempt to open a repository at repos_root_dirent. */
      SVN_ERR(svn_repos_open3(&access->repos, repos_root_dirent, NULL,
                              access->pool, scratch_pool));
    }

  fs_path = &dirent[strlen(repos_root_dirent)];

  /* Get the filesystem. */
  fs = svn_repos_fs(access->repos);

  /* Find HEAD and the revision root */
  SVN_ERR(svn_fs_youngest_rev(&youngest_rev, fs, scratch_pool));
  SVN_ERR(svn_fs_revision_root(&root, fs, youngest_rev, access->pool));

  /* Special case: non-existent paths may be handled as "empty" contents. */
  SVN_ERR(svn_fs_check_path(&node_kind, root, fs_path, scratch_pool));
  if (node_kind != svn_node_file)
    return svn_error_trace(handle_missing_file(stream, checksum, access,
                                               url, must_exist, node_kind));

  /* Fetch checksum and see whether we already have a matching config */
  SVN_ERR(svn_fs_file_checksum(checksum, svn_checksum_md5, root, fs_path,
                               TRUE, access->pool));

  *stream = representation_stream(root, fs_path, access->pool);

  return SVN_NO_ERROR;
}

/* Open the file at PATH, return its content checksum in CHECKSUM and the
 * content itself through *STREAM.  Allocate those with the lifetime of
 * ACCESS.
 */
static svn_error_t *
get_file_config(svn_stream_t **stream,
                svn_checksum_t **checksum,
                config_access_t *access,
                const char *path,
                svn_boolean_t must_exist,
                apr_pool_t *scratch_pool)
{
  svn_stringbuf_t *contents;
  svn_node_kind_t node_kind;

  /* Special case: non-existent paths may be handled as "empty" contents. */
  SVN_ERR(svn_io_check_path(path, &node_kind, scratch_pool));
  if (node_kind != svn_node_file)
    return svn_error_trace(handle_missing_file(stream, checksum, access,
                                               path, must_exist, node_kind));

  /* Now, we should be able to read the file. */
  SVN_ERR(svn_stringbuf_from_file2(&contents, path, access->pool));

  /* calculate MD5 over the whole file contents */
  SVN_ERR(svn_checksum(checksum, svn_checksum_md5,
                       contents->data, contents->len, access->pool));
  *stream = svn_stream_from_stringbuf(contents, access->pool);

  return SVN_NO_ERROR;
}

/* Read the configuration from path, URL or registry sub-tree PATH, return
 * its content checksum in CHECKSUM and the content itself through *STREAM.
 * Allocate those with the lifetime of ACCESS.
 */
static svn_error_t *
get_generic_config(svn_stream_t **stream,
                   svn_checksum_t **checksum,
                   config_access_t *access,
                   const char *path,
                   svn_boolean_t must_exist,
                   apr_pool_t *scratch_pool)
{
  svn_stringbuf_t *contents = svn_stringbuf_create_empty(access->pool);
  svn_config_t *config;

  /* Read the configuration and serialize it into CONTENTS.
   * That copy can then be processed by the authz parser etc. */
  SVN_ERR(svn_config_read3(&config, path, must_exist, TRUE, TRUE,
                           scratch_pool));
  SVN_ERR(svn_config__write(svn_stream_from_stringbuf(contents, scratch_pool),
                            config, scratch_pool));

  /* calculate MD5 over the whole file contents */
  SVN_ERR(svn_checksum(checksum, svn_checksum_md5,
                       contents->data, contents->len, access->pool));
  *stream = svn_stream_from_stringbuf(contents, access->pool);

  return SVN_NO_ERROR;
}

config_access_t *
svn_repos__create_config_access(svn_repos_t *repos_hint,
                                apr_pool_t *result_pool)
{
  apr_pool_t *pool = svn_pool_create(result_pool);
  config_access_t *result = apr_pcalloc(pool, sizeof(*result));

  result->repos = repos_hint;
  result->pool = pool;

  return result;
}

void
svn_repos__destroy_config_access(config_access_t *access)
{
  svn_pool_destroy(access->pool);
}

svn_error_t *
svn_repos__get_config(svn_stream_t **stream,
                      svn_checksum_t **checksum,
                      config_access_t *access,
                      const char *path,
                      svn_boolean_t must_exist,
                      apr_pool_t *scratch_pool)
{
  svn_error_t *err;
  /* Directly access the config data. */
  if (svn_path_is_url(path))
    err = get_repos_config(stream, checksum, access, path, must_exist,
                           scratch_pool);
  else
    err = get_file_config(stream, checksum, access, path, must_exist,
                          scratch_pool);

  /* Fallback to indirect access using the generic config file parser.
   * This is mainly used for registry support under Win32. */
  if (err)
    {
      svn_error_t *err2 = get_generic_config(stream, checksum, access, path,
                                             must_exist, scratch_pool);
      if (err2)
        {
          svn_error_clear(err2);
        }
      else
        {
          svn_error_clear(err);
          err = SVN_NO_ERROR;
        }
    }

  return svn_error_trace(err);
}
