/*
 * inherited_props.c : ra_serf implementation of svn_ra_get_inherited_props
 *
 * ====================================================================
 *    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 <apr_tables.h>
#include <apr_xml.h>

#include "svn_hash.h"
#include "svn_path.h"
#include "svn_ra.h"
#include "svn_string.h"
#include "svn_xml.h"
#include "svn_props.h"
#include "svn_base64.h"

#include "private/svn_dav_protocol.h"
#include "../libsvn_ra/ra_loader.h"
#include "svn_private_config.h"
#include "ra_serf.h"


/* The current state of our XML parsing. */
typedef enum iprops_state_e {
  INITIAL = XML_STATE_INITIAL,
  IPROPS_REPORT,
  IPROPS_ITEM,
  IPROPS_PATH,
  IPROPS_PROPNAME,
  IPROPS_PROPVAL
} iprops_state_e;

/* Struct for accumulating inherited props. */
typedef struct iprops_context_t {
  /* The depth-first ordered array of svn_prop_inherited_item_t *
     structures we are building. */
  apr_array_header_t *iprops;

  /* Pool in which to allocate elements of IPROPS. */
  apr_pool_t *pool;

  /* The repository's root URL. */
  const char *repos_root_url;

  /* Current property name */
  svn_stringbuf_t *curr_propname;

  /* Current element in IPROPS. */
  svn_prop_inherited_item_t *curr_iprop;

  /* Path we are finding inherited properties for.  This is relative to
     the RA session passed to svn_ra_serf__get_inherited_props. */
  const char *path;
  /* The revision of PATH*/
  svn_revnum_t revision;
} iprops_context_t;

#define S_ SVN_XML_NAMESPACE
static const svn_ra_serf__xml_transition_t iprops_table[] = {
  { INITIAL, S_, SVN_DAV__INHERITED_PROPS_REPORT, IPROPS_REPORT,
    FALSE, { NULL }, FALSE },

  { IPROPS_REPORT, S_, SVN_DAV__IPROP_ITEM, IPROPS_ITEM,
    FALSE, { NULL }, TRUE },

  { IPROPS_ITEM, S_, SVN_DAV__IPROP_PATH, IPROPS_PATH,
    TRUE, { NULL }, TRUE },

  { IPROPS_ITEM, S_, SVN_DAV__IPROP_PROPNAME, IPROPS_PROPNAME,
    TRUE, { NULL }, TRUE },

  { IPROPS_ITEM, S_, SVN_DAV__IPROP_PROPVAL, IPROPS_PROPVAL,
    TRUE, { "?V:encoding", NULL }, TRUE },

  { 0 }
};

/* Conforms to svn_ra_serf__xml_opened_t */
static svn_error_t *
iprops_opened(svn_ra_serf__xml_estate_t *xes,
              void *baton,
              int entered_state,
              const svn_ra_serf__dav_props_t *tag,
              apr_pool_t *scratch_pool)
{
  iprops_context_t *iprops_ctx = baton;

  if (entered_state == IPROPS_ITEM)
    {
      svn_stringbuf_setempty(iprops_ctx->curr_propname);

      iprops_ctx->curr_iprop = apr_pcalloc(iprops_ctx->pool,
                                           sizeof(*iprops_ctx->curr_iprop));

      iprops_ctx->curr_iprop->prop_hash = apr_hash_make(iprops_ctx->pool);
    }
  return SVN_NO_ERROR;
}

/* Conforms to svn_ra_serf__xml_closed_t  */
static svn_error_t *
iprops_closed(svn_ra_serf__xml_estate_t *xes,
              void *baton,
              int leaving_state,
              const svn_string_t *cdata,
              apr_hash_t *attrs,
              apr_pool_t *scratch_pool)
{
  iprops_context_t *iprops_ctx = baton;

  if (leaving_state == IPROPS_ITEM)
    {
      APR_ARRAY_PUSH(iprops_ctx->iprops, svn_prop_inherited_item_t *) =
        iprops_ctx->curr_iprop;

      iprops_ctx->curr_iprop = NULL;
    }
  else if (leaving_state == IPROPS_PATH)
    {
      /* Every <iprop-item> has a single <iprop-path> */
      if (iprops_ctx->curr_iprop->path_or_url)
        return svn_error_create(SVN_ERR_XML_MALFORMED, NULL, NULL);

      iprops_ctx->curr_iprop->path_or_url =
                                apr_pstrdup(iprops_ctx->pool, cdata->data);
    }
  else if (leaving_state == IPROPS_PROPNAME)
    {
      if (iprops_ctx->curr_propname->len)
        return svn_error_create(SVN_ERR_XML_MALFORMED, NULL, NULL);

      /* Store propname for value */
      svn_stringbuf_set(iprops_ctx->curr_propname, cdata->data);
    }
  else if (leaving_state == IPROPS_PROPVAL)
    {
      const char *encoding;
      const svn_string_t *val_str;

      if (! iprops_ctx->curr_propname->len)
        return svn_error_create(SVN_ERR_XML_MALFORMED, NULL, NULL);

      encoding = svn_hash_gets(attrs, "V:encoding");

      if (encoding)
        {
          if (strcmp(encoding, "base64") != 0)
            return svn_error_createf(SVN_ERR_XML_MALFORMED,
                                     NULL,
                                     _("Got unrecognized encoding '%s'"),
                                     encoding);

          /* Decode into the right pool.  */
          val_str = svn_base64_decode_string(cdata, iprops_ctx->pool);
        }
      else
        {
          /* Copy into the right pool.  */
          val_str = svn_string_dup(cdata, iprops_ctx->pool);
        }

      svn_hash_sets(iprops_ctx->curr_iprop->prop_hash,
                    apr_pstrdup(iprops_ctx->pool,
                                iprops_ctx->curr_propname->data),
                    val_str);
      /* Clear current propname. */
      svn_stringbuf_setempty(iprops_ctx->curr_propname);
    }
  else
    SVN_ERR_MALFUNCTION(); /* Invalid transition table */

  return SVN_NO_ERROR;
}

static svn_error_t *
create_iprops_body(serf_bucket_t **bkt,
                   void *baton,
                   serf_bucket_alloc_t *alloc,
                   apr_pool_t *pool /* request pool */,
                   apr_pool_t *scratch_pool)
{
  iprops_context_t *iprops_ctx = baton;
  serf_bucket_t *body_bkt;

  body_bkt = serf_bucket_aggregate_create(alloc);

  svn_ra_serf__add_open_tag_buckets(body_bkt, alloc,
                                    "S:" SVN_DAV__INHERITED_PROPS_REPORT,
                                    "xmlns:S", SVN_XML_NAMESPACE,
                                    SVN_VA_NULL);
  svn_ra_serf__add_tag_buckets(body_bkt,
                               "S:" SVN_DAV__REVISION,
                               apr_ltoa(pool, iprops_ctx->revision),
                               alloc);
  svn_ra_serf__add_tag_buckets(body_bkt, "S:" SVN_DAV__PATH,
                               iprops_ctx->path, alloc);
  svn_ra_serf__add_close_tag_buckets(body_bkt, alloc,
                                     "S:" SVN_DAV__INHERITED_PROPS_REPORT);
  *bkt = body_bkt;
  return SVN_NO_ERROR;
}

/* Per request information for get_iprops_via_more_requests */
typedef struct iprop_rq_info_t
{
  const char *relpath;
  const char *urlpath;
  apr_hash_t *props;
  svn_ra_serf__handler_t *handler;
} iprop_rq_info_t;


/* Assumes session reparented to the repository root. The old session
   root is passed as session_url */
static svn_error_t *
get_iprops_via_more_requests(svn_ra_session_t *ra_session,
                             apr_array_header_t **iprops,
                             const char *session_url,
                             const char *path,
                             svn_revnum_t revision,
                             apr_pool_t *result_pool,
                             apr_pool_t *scratch_pool)
{
  svn_ra_serf__session_t *session = ra_session->priv;
  const char *url;
  const char *relpath;
  apr_array_header_t *rq_info;
  apr_pool_t *iterpool = svn_pool_create(scratch_pool);
  apr_interval_time_t waittime_left = session->timeout;
  const svn_revnum_t rev_marker = SVN_INVALID_REVNUM;
  int i;

  rq_info = apr_array_make(scratch_pool, 16, sizeof(iprop_rq_info_t *));

  if (!svn_path_is_empty(path))
    url = svn_path_url_add_component2(session_url, path, scratch_pool);
  else
    url = session_url;

  relpath = svn_uri_skip_ancestor(session->repos_root_str, url, scratch_pool);

  /* Create all requests */
  while (relpath[0] != '\0')
    {
      iprop_rq_info_t *rq = apr_pcalloc(scratch_pool, sizeof(*rq));

      relpath = svn_relpath_dirname(relpath, scratch_pool);

      rq->relpath = relpath;
      rq->props = apr_hash_make(scratch_pool);

      SVN_ERR(svn_ra_serf__get_stable_url(&rq->urlpath, NULL, session,
                                          svn_path_url_add_component2(
                                                session->repos_root.path,
                                                relpath, scratch_pool),
                                          revision,
                                          scratch_pool, scratch_pool));

      SVN_ERR(svn_ra_serf__create_propfind_handler(
                                          &rq->handler, session,
                                          rq->urlpath,
                                          rev_marker, "0", all_props,
                                          svn_ra_serf__deliver_svn_props,
                                          rq->props,
                                          scratch_pool));

      /* Allow ignoring authz problems */
      rq->handler->no_fail_on_http_failure_status = TRUE;

      svn_ra_serf__request_create(rq->handler);

      APR_ARRAY_PUSH(rq_info, iprop_rq_info_t *) = rq;
    }

  while (TRUE)
    {
      svn_pool_clear(iterpool);

      SVN_ERR(svn_ra_serf__context_run(session, &waittime_left, iterpool));

      for (i = 0; i < rq_info->nelts; i++)
        {
          iprop_rq_info_t *rq = APR_ARRAY_IDX(rq_info, i, iprop_rq_info_t *);

          if (!rq->handler->done)
            break;
        }

      if (i >= rq_info->nelts)
        break; /* All requests done */
    }

  *iprops = apr_array_make(result_pool, rq_info->nelts,
                           sizeof(svn_prop_inherited_item_t *));

  /* And now create the result set in depth-first order. */
  for (i = rq_info->nelts - 1; i >= 0; i--)
    {
      iprop_rq_info_t *rq = APR_ARRAY_IDX(rq_info, i, iprop_rq_info_t *);
      apr_hash_t *node_props;
      svn_prop_inherited_item_t *new_iprop;

      if (rq->handler->sline.code != 207 && rq->handler->sline.code != 403)
        {
          if (rq->handler->server_error)
            SVN_ERR(svn_ra_serf__server_error_create(rq->handler,
                                                     scratch_pool));

          return svn_error_trace(svn_ra_serf__unexpected_status(rq->handler));
        }

      node_props = rq->props;

      svn_ra_serf__keep_only_regular_props(node_props, scratch_pool);

      if (!apr_hash_count(node_props))
        continue;

      new_iprop = apr_palloc(result_pool, sizeof(*new_iprop));
      new_iprop->path_or_url = apr_pstrdup(result_pool, rq->relpath);
      new_iprop->prop_hash = svn_prop_hash_dup(node_props, result_pool);
      APR_ARRAY_PUSH(*iprops, svn_prop_inherited_item_t *) = new_iprop;
    }

  return SVN_NO_ERROR;
}

/* Request a inherited-props-report from the URL attached to RA_SESSION,
   and fill the IPROPS array hash with the results.  */
svn_error_t *
svn_ra_serf__get_inherited_props(svn_ra_session_t *ra_session,
                                 apr_array_header_t **iprops,
                                 const char *path,
                                 svn_revnum_t revision,
                                 apr_pool_t *result_pool,
                                 apr_pool_t *scratch_pool)
{
  iprops_context_t *iprops_ctx;
  svn_ra_serf__session_t *session = ra_session->priv;
  svn_ra_serf__handler_t *handler;
  svn_ra_serf__xml_context_t *xmlctx;
  const char *req_url;
  svn_boolean_t iprop_capable;

  SVN_ERR(svn_ra_serf__has_capability(ra_session, &iprop_capable,
                                      SVN_RA_CAPABILITY_INHERITED_PROPS,
                                      scratch_pool));

  if (!iprop_capable)
    {
      svn_error_t *err;
      const char *reparent_uri = NULL;
      const char *session_uri;
      const char *repos_root_url;

      SVN_ERR(svn_ra_serf__get_repos_root(ra_session, &repos_root_url,
                                          scratch_pool));

      session_uri = apr_pstrdup(scratch_pool, session->session_url_str);
      if (strcmp(repos_root_url, session->session_url_str) != 0)
        {
          reparent_uri  = session_uri;
          SVN_ERR(svn_ra_serf__reparent(ra_session, repos_root_url,
                                        scratch_pool));
        }

      err = get_iprops_via_more_requests(ra_session, iprops, session_uri, path,
                                         revision, result_pool, scratch_pool);

      if (reparent_uri)
        err = svn_error_compose_create(err,
                                       svn_ra_serf__reparent(ra_session,
                                                             reparent_uri ,
                                                             scratch_pool));

      return svn_error_trace(err);
    }

  SVN_ERR(svn_ra_serf__get_stable_url(&req_url,
                                      NULL /* latest_revnum */,
                                      session,
                                      NULL /* url */,
                                      revision,
                                      scratch_pool, scratch_pool));

  SVN_ERR_ASSERT(session->repos_root_str);

  iprops_ctx = apr_pcalloc(scratch_pool, sizeof(*iprops_ctx));
  iprops_ctx->repos_root_url = session->repos_root_str;
  iprops_ctx->pool = result_pool;
  iprops_ctx->curr_propname = svn_stringbuf_create_empty(scratch_pool);
  iprops_ctx->curr_iprop = NULL;
  iprops_ctx->iprops = apr_array_make(result_pool, 1,
                                       sizeof(svn_prop_inherited_item_t *));
  iprops_ctx->path = path;
  iprops_ctx->revision = revision;

  xmlctx = svn_ra_serf__xml_context_create(iprops_table,
                                           iprops_opened, iprops_closed,
                                           NULL,
                                           iprops_ctx,
                                           scratch_pool);
  handler = svn_ra_serf__create_expat_handler(session, xmlctx, NULL,
                                              scratch_pool);

  handler->method = "REPORT";
  handler->path = req_url;

  handler->body_delegate = create_iprops_body;
  handler->body_delegate_baton = iprops_ctx;
  handler->body_type = "text/xml";

  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));

  *iprops = iprops_ctx->iprops;

  return SVN_NO_ERROR;
}
