/*
 * get_file.c :  entry point for update RA functions for ra_serf
 *
 * ====================================================================
 *    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.
 * ====================================================================
 */



#define APR_WANT_STRFUNC
#include <apr_version.h>
#include <apr_want.h>

#include <apr_uri.h>

#include <serf.h>

#include "svn_private_config.h"
#include "svn_hash.h"
#include "svn_pools.h"
#include "svn_ra.h"
#include "svn_delta.h"
#include "svn_path.h"
#include "svn_props.h"

#include "private/svn_dep_compat.h"
#include "private/svn_string_private.h"

#include "ra_serf.h"
#include "../libsvn_ra/ra_loader.h"




/*
 * This structure represents a single request to GET (fetch) a file with
 * its associated Serf session/connection.
 */
typedef struct stream_ctx_t {

  /* The handler representing this particular fetch.  */
  svn_ra_serf__handler_t *handler;

  /* Have we read our response headers yet? */
  svn_boolean_t read_headers;

  svn_ra_serf__session_t *session;

  /* This flag is set when our response is aborted before we reach the
   * end and we decide to requeue this request.
   */
  svn_boolean_t aborted_read;
  apr_off_t aborted_read_size;

  /* This is the amount of data that we have read so far. */
  apr_off_t read_size;

  /* If we're writing this file to a stream, this will be non-NULL. */
  svn_stream_t *result_stream;

} stream_ctx_t;



/** Routines called when we are fetching a file */

static svn_error_t *
headers_fetch(serf_bucket_t *headers,
              void *baton,
              apr_pool_t *pool /* request pool */,
              apr_pool_t *scratch_pool)
{
  stream_ctx_t *fetch_ctx = baton;

  if (fetch_ctx->session->using_compression != svn_tristate_false)
    {
      serf_bucket_headers_setn(headers, "Accept-Encoding", "gzip");
    }

  return SVN_NO_ERROR;
}

static svn_error_t *
cancel_fetch(serf_request_t *request,
             serf_bucket_t *response,
             int status_code,
             void *baton)
{
  stream_ctx_t *fetch_ctx = baton;

  /* Uh-oh.  Our connection died on us.
   *
   * The core ra_serf layer will requeue our request - we just need to note
   * that we got cut off in the middle of our song.
   */
  if (!response)
    {
      /* If we already started the fetch and opened the file handle, we need
       * to hold subsequent read() ops until we get back to where we were
       * before the close and we can then resume the textdelta() calls.
       */
      if (fetch_ctx->read_headers)
        {
          if (!fetch_ctx->aborted_read && fetch_ctx->read_size)
            {
              fetch_ctx->aborted_read = TRUE;
              fetch_ctx->aborted_read_size = fetch_ctx->read_size;
            }
          fetch_ctx->read_size = 0;
        }

      return SVN_NO_ERROR;
    }

  /* We have no idea what went wrong. */
  SVN_ERR_MALFUNCTION();
}


/* Helper svn_ra_serf__get_file(). Attempts to fetch file contents
 * using SESSION->wc_callbacks->get_wc_contents() if sha1 property is
 * present in PROPS.
 *
 * Sets *FOUND_P to TRUE if file contents was successfully fetched.
 *
 * Performs all temporary allocations in POOL.
 */
static svn_error_t *
try_get_wc_contents(svn_boolean_t *found_p,
                    svn_ra_serf__session_t *session,
                    const char *sha1_checksum_prop,
                    svn_stream_t *dst_stream,
                    apr_pool_t *pool)
{
  svn_checksum_t *checksum;
  svn_stream_t *wc_stream;
  svn_error_t *err;

  /* No contents found by default. */
  *found_p = FALSE;

  if (!session->wc_callbacks->get_wc_contents
      || sha1_checksum_prop == NULL)
    {
      /* Nothing to do. */
      return SVN_NO_ERROR;
    }

  SVN_ERR(svn_checksum_parse_hex(&checksum, svn_checksum_sha1,
                                 sha1_checksum_prop, pool));

  err = session->wc_callbacks->get_wc_contents(
          session->wc_callback_baton, &wc_stream, checksum, pool);

  if (err)
    {
      svn_error_clear(err);

      /* Ignore errors for now. */
      return SVN_NO_ERROR;
    }

  if (wc_stream)
    {
        SVN_ERR(svn_stream_copy3(wc_stream,
                                 svn_stream_disown(dst_stream, pool),
                                 NULL, NULL, pool));
      *found_p = TRUE;
    }

  return SVN_NO_ERROR;
}

/* -----------------------------------------------------------------------
   svn_ra_get_file() specific */

/* Implements svn_ra_serf__response_handler_t */
static svn_error_t *
handle_stream(serf_request_t *request,
              serf_bucket_t *response,
              void *handler_baton,
              apr_pool_t *pool)
{
  stream_ctx_t *fetch_ctx = handler_baton;
  apr_status_t status;

  if (fetch_ctx->handler->sline.code != 200)
    return svn_error_trace(svn_ra_serf__unexpected_status(fetch_ctx->handler));

  while (1)
    {
      const char *data;
      apr_size_t len;

      status = serf_bucket_read(response, 8000, &data, &len);
      if (SERF_BUCKET_READ_ERROR(status))
        {
          return svn_ra_serf__wrap_err(status, NULL);
        }

      fetch_ctx->read_size += len;

      if (fetch_ctx->aborted_read)
        {
          apr_off_t skip;

          /* We haven't caught up to where we were before. */
          if (fetch_ctx->read_size < fetch_ctx->aborted_read_size)
            {
              /* Eek.  What did the file shrink or something? */
              if (APR_STATUS_IS_EOF(status))
                {
                  SVN_ERR_MALFUNCTION();
                }

              /* Skip on to the next iteration of this loop. */
              if (APR_STATUS_IS_EAGAIN(status))
                {
                  return svn_ra_serf__wrap_err(status, NULL);
                }
              continue;
            }

          /* Woo-hoo.  We're back. */
          fetch_ctx->aborted_read = FALSE;

          /* Increment data and len by the difference. */
          skip = len - (fetch_ctx->read_size - fetch_ctx->aborted_read_size);
          data += skip;
          len -= (apr_size_t)skip;
        }

      if (len)
        {
          apr_size_t written_len;

          written_len = len;

          SVN_ERR(svn_stream_write(fetch_ctx->result_stream, data,
                                   &written_len));
        }

      if (status)
        {
          return svn_ra_serf__wrap_err(status, NULL);
        }
    }
  /* not reached */
}

/* Baton for get_file_prop_cb */
struct file_prop_baton_t
{
  apr_pool_t *result_pool;
  svn_node_kind_t kind;
  apr_hash_t *props;
  const char *sha1_checksum;
};

/* Implements svn_ra_serf__prop_func_t for svn_ra_serf__get_file */
static svn_error_t *
get_file_prop_cb(void *baton,
                 const char *path,
                 const char *ns,
                 const char *name,
                 const svn_string_t *value,
                 apr_pool_t *scratch_pool)
{
  struct file_prop_baton_t *fb = baton;
  const char *svn_name;

  if (strcmp(ns, "DAV:") == 0 && strcmp(name, "resourcetype") == 0)
    {
      const char *val = value->data;

      if (strcmp(val, "collection") == 0)
        fb->kind = svn_node_dir;
      else
        fb->kind = svn_node_file;

      return SVN_NO_ERROR;
    }
  else if (strcmp(ns, SVN_DAV_PROP_NS_DAV) == 0
           && strcmp(name, "sha1-checksum") == 0)
    {
      fb->sha1_checksum = apr_pstrdup(fb->result_pool, value->data);
    }

  if (!fb->props)
    return SVN_NO_ERROR;

  svn_name = svn_ra_serf__svnname_from_wirename(ns, name, fb->result_pool);
  if (svn_name)
    {
      svn_hash_sets(fb->props, svn_name,
                    svn_string_dup(value, fb->result_pool));
    }
  return SVN_NO_ERROR;
}

svn_error_t *
svn_ra_serf__get_file(svn_ra_session_t *ra_session,
                      const char *path,
                      svn_revnum_t revision,
                      svn_stream_t *stream,
                      svn_revnum_t *fetched_rev,
                      apr_hash_t **props,
                      apr_pool_t *result_pool)
{
  svn_ra_serf__session_t *session = ra_session->priv;
  const char *fetch_url;
  const svn_ra_serf__dav_props_t *which_props;
  svn_ra_serf__handler_t *propfind_handler;
  apr_pool_t *scratch_pool = svn_pool_create(result_pool);
  struct file_prop_baton_t fb;

  /* Fetch properties. */

  fetch_url = svn_path_url_add_component2(session->session_url.path, path,
                                          scratch_pool);

  /* The simple case is if we want HEAD - then a GET on the fetch_url is fine.
   *
   * Otherwise, we need to get the baseline version for this particular
   * revision and then fetch that file.
   */
  if (SVN_IS_VALID_REVNUM(revision) || fetched_rev)
    {
      SVN_ERR(svn_ra_serf__get_stable_url(&fetch_url, fetched_rev,
                                          session,
                                          fetch_url, revision,
                                          scratch_pool, scratch_pool));
      revision = SVN_INVALID_REVNUM;
    }
  /* REVISION is always SVN_INVALID_REVNUM  */
  SVN_ERR_ASSERT(!SVN_IS_VALID_REVNUM(revision));

  if (props)
      which_props = all_props;
  else if (stream && session->wc_callbacks->get_wc_contents)
      which_props = type_and_checksum_props;
  else
      which_props = check_path_props;

  fb.result_pool = result_pool;
  fb.props = props ? apr_hash_make(result_pool) : NULL;
  fb.kind = svn_node_unknown;
  fb.sha1_checksum = NULL;

  SVN_ERR(svn_ra_serf__create_propfind_handler(&propfind_handler, session,
                                               fetch_url, SVN_INVALID_REVNUM,
                                               "0", which_props,
                                               get_file_prop_cb, &fb,
                                               scratch_pool));

  SVN_ERR(svn_ra_serf__context_run_one(propfind_handler, scratch_pool));

  /* Verify that resource type is not collection. */
  if (fb.kind != svn_node_file)
    {
      return svn_error_create(SVN_ERR_FS_NOT_FILE, NULL,
                              _("Can't get text contents of a directory"));
    }

  if (props)
    *props = fb.props;

  if (stream)
    {
      svn_boolean_t found;
      SVN_ERR(try_get_wc_contents(&found, session, fb.sha1_checksum, stream,
                                  scratch_pool));

      /* No contents found in the WC, let's fetch from server. */
      if (!found)
        {
          stream_ctx_t *stream_ctx;
          svn_ra_serf__handler_t *handler;

          /* Create the fetch context. */
          stream_ctx = apr_pcalloc(scratch_pool, sizeof(*stream_ctx));
          stream_ctx->result_stream = stream;
          stream_ctx->session = session;

          handler = svn_ra_serf__create_handler(session, scratch_pool);

          handler->method = "GET";
          handler->path = fetch_url;

          handler->custom_accept_encoding = TRUE;
          handler->no_dav_headers = TRUE;

          handler->header_delegate = headers_fetch;
          handler->header_delegate_baton = stream_ctx;

          handler->response_handler = handle_stream;
          handler->response_baton = stream_ctx;

          handler->response_error = cancel_fetch;
          handler->response_error_baton = stream_ctx;

          stream_ctx->handler = handler;

          SVN_ERR(svn_ra_serf__context_run_one(handler, scratch_pool));

          if (handler->sline.code != 200)
            return svn_error_trace(svn_ra_serf__unexpected_status(handler));
        }
    }

  svn_pool_destroy(scratch_pool);

  return SVN_NO_ERROR;
}
