/* changes.h --- FSX changed paths lists container
 *
 * ====================================================================
 *    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_private_config.h"
#include "svn_sorts.h"

#include "private/svn_packed_data.h"

#include "changes.h"
#include "string_table.h"
#include "temp_serializer.h"

/* These flags will be used with the FLAGS field in binary_change_t.
 */

/* the change contains a text modification */
#define CHANGE_TEXT_MOD     0x00001

/* the change contains a property modification */
#define CHANGE_PROP_MOD     0x00002

/* the change contains a mergeinfo modification */
#define CHANGE_MERGEINFO_MOD 0x00004

/* (flags & CHANGE_NODE_MASK) >> CHANGE_NODE_SHIFT extracts the node type */
#define CHANGE_NODE_SHIFT   0x00003
#define CHANGE_NODE_MASK    0x00018

/* node types according to svn_node_kind_t */
#define CHANGE_NODE_NONE    0x00000
#define CHANGE_NODE_FILE    0x00008
#define CHANGE_NODE_DIR     0x00010
#define CHANGE_NODE_UNKNOWN 0x00018

/* (flags & CHANGE_KIND_MASK) >> CHANGE_KIND_SHIFT extracts the change type */
#define CHANGE_KIND_SHIFT   0x00005
#define CHANGE_KIND_MASK    0x00060

/* node types according to svn_fs_path_change_kind_t */
#define CHANGE_KIND_MODIFY  0x00000
#define CHANGE_KIND_ADD     0x00020
#define CHANGE_KIND_DELETE  0x00040
#define CHANGE_KIND_REPLACE 0x00060

/* Our internal representation of a change */
typedef struct binary_change_t
{
  /* define the kind of change and what specific information is present */
  int flags;

  /* Path of the change. */
  apr_size_t path;

  /* copy-from information.
   * Not present if COPYFROM_REV is SVN_INVALID_REVNUM. */
  svn_revnum_t copyfrom_rev;
  apr_size_t copyfrom_path;

} binary_change_t;

/* The actual container object.  Change lists are concatenated into CHANGES
 * and and their begins and ends are stored in OFFSETS.
 */
struct svn_fs_x__changes_t
{
  /* The paths - either in 'builder' mode or finalized mode.
   * The respective other pointer will be NULL. */
  string_table_builder_t *builder;
  string_table_t *paths;

  /* All changes of all change lists concatenated.
   * Array elements are binary_change_t.structs (not pointer!) */
  apr_array_header_t *changes;

  /* [Offsets[index] .. Offsets[index+1]) is the range in CHANGES that
   * forms the contents of change list INDEX. */
  apr_array_header_t *offsets;
};

/* Create and return a new container object, allocated in RESULT_POOL with
 * an initial capacity of INITIAL_COUNT changes.  The PATH and BUILDER
 * members must be initialized by the caller afterwards.
 */
static svn_fs_x__changes_t *
changes_create_body(apr_size_t initial_count,
                    apr_pool_t *result_pool)
{
  svn_fs_x__changes_t *changes = apr_pcalloc(result_pool, sizeof(*changes));

  changes->changes = apr_array_make(result_pool, (int)initial_count,
                                    sizeof(binary_change_t));
  changes->offsets = apr_array_make(result_pool, 16, sizeof(int));
  APR_ARRAY_PUSH(changes->offsets, int) = 0;

  return changes;
}

svn_fs_x__changes_t *
svn_fs_x__changes_create(apr_size_t initial_count,
                         apr_pool_t *result_pool)
{
  svn_fs_x__changes_t *changes = changes_create_body(initial_count,
                                                     result_pool);
  changes->builder = svn_fs_x__string_table_builder_create(result_pool);

  return changes;
}

/* Add CHANGE to the latest change list in CHANGES.
 */
static svn_error_t *
append_change(svn_fs_x__changes_t *changes,
              svn_fs_x__change_t *change)
{
  binary_change_t binary_change = { 0 };

  /* CHANGE must be sufficiently complete */
  SVN_ERR_ASSERT(change);
  SVN_ERR_ASSERT(change->path.data);

  /* define the kind of change and what specific information is present */
  binary_change.flags = (change->text_mod ? CHANGE_TEXT_MOD : 0)
                      | (change->prop_mod ? CHANGE_PROP_MOD : 0)
                      | (change->mergeinfo_mod == svn_tristate_true
                                          ? CHANGE_MERGEINFO_MOD : 0)
                      | ((int)change->change_kind << CHANGE_KIND_SHIFT)
                      | ((int)change->node_kind << CHANGE_NODE_SHIFT);

  /* Path of the change. */
  binary_change.path
    = svn_fs_x__string_table_builder_add(changes->builder,
                                         change->path.data,
                                         change->path.len);

  /* copy-from information, if presence is indicated by FLAGS */
  if (SVN_IS_VALID_REVNUM(change->copyfrom_rev))
    {
      binary_change.copyfrom_rev = change->copyfrom_rev;
      binary_change.copyfrom_path
        = svn_fs_x__string_table_builder_add(changes->builder,
                                             change->copyfrom_path,
                                             0);
    }
  else
    {
      binary_change.copyfrom_rev = SVN_INVALID_REVNUM;
      binary_change.copyfrom_path = 0;
    }

  APR_ARRAY_PUSH(changes->changes, binary_change_t) = binary_change;

  return SVN_NO_ERROR;
}

svn_error_t *
svn_fs_x__changes_append_list(apr_size_t *list_index,
                              svn_fs_x__changes_t *changes,
                              apr_array_header_t *list)
{
  int i;

  /* CHANGES must be in 'builder' mode */
  SVN_ERR_ASSERT(changes->builder);
  SVN_ERR_ASSERT(changes->paths == NULL);

  /* simply append the list and all changes */
  for (i = 0; i < list->nelts; ++i)
    SVN_ERR(append_change(changes, APR_ARRAY_IDX(list, i, svn_fs_x__change_t *)));

  /* terminate the list by storing the next changes offset */
  APR_ARRAY_PUSH(changes->offsets, int) = changes->changes->nelts;
  *list_index = (apr_size_t)(changes->offsets->nelts - 2);

  return SVN_NO_ERROR;
}

apr_size_t
svn_fs_x__changes_estimate_size(const svn_fs_x__changes_t *changes)
{
  /* CHANGES must be in 'builder' mode */
  if (changes->builder == NULL)
    return 0;

  /* string table code makes its own prediction,
   * changes should be < 10 bytes each,
   * some static overhead should be assumed */
  return svn_fs_x__string_table_builder_estimate_size(changes->builder)
       + changes->changes->nelts * 10
       + 100;
}

svn_error_t *
svn_fs_x__changes_get_list(apr_array_header_t **list,
                           const svn_fs_x__changes_t *changes,
                           apr_size_t idx,
                           svn_fs_x__changes_context_t *context,
                           apr_pool_t *result_pool)
{
  int list_first;
  int list_last;
  int first;
  int last;
  int i;

  /* CHANGES must be in 'finalized' mode */
  SVN_ERR_ASSERT(changes->builder == NULL);
  SVN_ERR_ASSERT(changes->paths);

  /* validate index */
  if (idx + 1 >= (apr_size_t)changes->offsets->nelts)
    return svn_error_createf(SVN_ERR_FS_CONTAINER_INDEX, NULL,
                             apr_psprintf(result_pool,
                                          _("Changes list index %%%s"
                                            " exceeds container size %%d"),
                                          APR_SIZE_T_FMT),
                             idx, changes->offsets->nelts - 1);

  /* range of changes to return */
  list_first = APR_ARRAY_IDX(changes->offsets, (int)idx, int);
  list_last = APR_ARRAY_IDX(changes->offsets, (int)idx + 1, int);

  /* Restrict it to the sub-range requested by the caller.
   * Clip the range to never exceed the list's content. */
  first = MIN(context->next + list_first, list_last);
  last = MIN(first + SVN_FS_X__CHANGES_BLOCK_SIZE, list_last);

  /* Indicate to the caller whether the end of the list has been reached. */
  context->eol = last == list_last;

  /* construct result */
  *list = apr_array_make(result_pool, last - first,
                         sizeof(svn_fs_x__change_t*));
  for (i = first; i < last; ++i)
    {
      const binary_change_t *binary_change
        = &APR_ARRAY_IDX(changes->changes, i, binary_change_t);

      /* convert BINARY_CHANGE into a standard FSX svn_fs_x__change_t */
      svn_fs_x__change_t *change = apr_pcalloc(result_pool, sizeof(*change));
      change->path.data = svn_fs_x__string_table_get(changes->paths,
                                                     binary_change->path,
                                                     &change->path.len,
                                                     result_pool);

      change->change_kind = (svn_fs_path_change_kind_t)
        ((binary_change->flags & CHANGE_KIND_MASK) >> CHANGE_KIND_SHIFT);
      change->text_mod = (binary_change->flags & CHANGE_TEXT_MOD) != 0;
      change->prop_mod = (binary_change->flags & CHANGE_PROP_MOD) != 0;
      change->mergeinfo_mod = (binary_change->flags & CHANGE_MERGEINFO_MOD)
                            ? svn_tristate_true
                            : svn_tristate_false;
      change->node_kind = (svn_node_kind_t)
        ((binary_change->flags & CHANGE_NODE_MASK) >> CHANGE_NODE_SHIFT);

      change->copyfrom_rev = binary_change->copyfrom_rev;
      change->copyfrom_known = TRUE;
      if (SVN_IS_VALID_REVNUM(binary_change->copyfrom_rev))
        change->copyfrom_path
          = svn_fs_x__string_table_get(changes->paths,
                                        binary_change->copyfrom_path,
                                        NULL,
                                        result_pool);

      /* add it to the result */
      APR_ARRAY_PUSH(*list, svn_fs_x__change_t*) = change;
    }

  return SVN_NO_ERROR;
}

svn_error_t *
svn_fs_x__write_changes_container(svn_stream_t *stream,
                                  const svn_fs_x__changes_t *changes,
                                  apr_pool_t *scratch_pool)
{
  int i;

  string_table_t *paths = changes->paths
                        ? changes->paths
                        : svn_fs_x__string_table_create(changes->builder,
                                                        scratch_pool);

  svn_packed__data_root_t *root = svn_packed__data_create_root(scratch_pool);

  /* one top-level stream for each array */
  svn_packed__int_stream_t *offsets_stream
    = svn_packed__create_int_stream(root, TRUE, FALSE);
  svn_packed__int_stream_t *changes_stream
    = svn_packed__create_int_stream(root, FALSE, FALSE);

  /* structure the CHANGES_STREAM such we can extract much of the redundancy
   * from the binary_change_t structs */
  svn_packed__create_int_substream(changes_stream, TRUE, FALSE);
  svn_packed__create_int_substream(changes_stream, TRUE, FALSE);
  svn_packed__create_int_substream(changes_stream, TRUE, TRUE);
  svn_packed__create_int_substream(changes_stream, TRUE, FALSE);

  /* serialize offsets array */
  for (i = 0; i < changes->offsets->nelts; ++i)
    svn_packed__add_uint(offsets_stream,
                         APR_ARRAY_IDX(changes->offsets, i, int));

  /* serialize changes array */
  for (i = 0; i < changes->changes->nelts; ++i)
    {
      const binary_change_t *change
        = &APR_ARRAY_IDX(changes->changes, i, binary_change_t);

      svn_packed__add_uint(changes_stream, change->flags);
      svn_packed__add_uint(changes_stream, change->path);

      svn_packed__add_int(changes_stream, change->copyfrom_rev);
      svn_packed__add_uint(changes_stream, change->copyfrom_path);
    }

  /* write to disk */
  SVN_ERR(svn_fs_x__write_string_table(stream, paths, scratch_pool));
  SVN_ERR(svn_packed__data_write(stream, root, scratch_pool));

  return SVN_NO_ERROR;
}

svn_error_t *
svn_fs_x__read_changes_container(svn_fs_x__changes_t **changes_p,
                                 svn_stream_t *stream,
                                 apr_pool_t *result_pool,
                                 apr_pool_t *scratch_pool)
{
  apr_size_t i;
  apr_size_t count;

  svn_fs_x__changes_t *changes = apr_pcalloc(result_pool, sizeof(*changes));

  svn_packed__data_root_t *root;
  svn_packed__int_stream_t *offsets_stream;
  svn_packed__int_stream_t *changes_stream;

  /* read from disk */
  SVN_ERR(svn_fs_x__read_string_table(&changes->paths, stream,
                                      result_pool, scratch_pool));

  SVN_ERR(svn_packed__data_read(&root, stream, result_pool, scratch_pool));
  offsets_stream = svn_packed__first_int_stream(root);
  changes_stream = svn_packed__next_int_stream(offsets_stream);

  /* read offsets array */
  count = svn_packed__int_count(offsets_stream);
  changes->offsets = apr_array_make(result_pool, (int)count, sizeof(int));
  for (i = 0; i < count; ++i)
    APR_ARRAY_PUSH(changes->offsets, int)
      = (int)svn_packed__get_uint(offsets_stream);

  /* read changes array */
  count
    = svn_packed__int_count(svn_packed__first_int_substream(changes_stream));
  changes->changes
    = apr_array_make(result_pool, (int)count, sizeof(binary_change_t));
  for (i = 0; i < count; ++i)
    {
      binary_change_t change;

      change.flags = (int)svn_packed__get_uint(changes_stream);
      change.path = (apr_size_t)svn_packed__get_uint(changes_stream);

      change.copyfrom_rev = (svn_revnum_t)svn_packed__get_int(changes_stream);
      change.copyfrom_path = (apr_size_t)svn_packed__get_uint(changes_stream);

      APR_ARRAY_PUSH(changes->changes, binary_change_t) = change;
    }

  *changes_p = changes;

  return SVN_NO_ERROR;
}

svn_error_t *
svn_fs_x__serialize_changes_container(void **data,
                                      apr_size_t *data_len,
                                      void *in,
                                      apr_pool_t *pool)
{
  svn_fs_x__changes_t *changes = in;
  svn_stringbuf_t *serialized;

  /* make a guesstimate on the size of the serialized data.  Erring on the
   * low side will cause the serializer to re-alloc its buffer. */
  apr_size_t size
    = changes->changes->elt_size * changes->changes->nelts
    + changes->offsets->elt_size * changes->offsets->nelts
    + 10 * changes->changes->elt_size
    + 100;

  /* serialize array header and all its elements */
  svn_temp_serializer__context_t *context
    = svn_temp_serializer__init(changes, sizeof(*changes), size, pool);

  /* serialize sub-structures */
  svn_fs_x__serialize_string_table(context, &changes->paths);
  svn_fs_x__serialize_apr_array(context, &changes->changes);
  svn_fs_x__serialize_apr_array(context, &changes->offsets);

  /* return the serialized result */
  serialized = svn_temp_serializer__get(context);

  *data = serialized->data;
  *data_len = serialized->len;

  return SVN_NO_ERROR;
}

svn_error_t *
svn_fs_x__deserialize_changes_container(void **out,
                                         void *data,
                                         apr_size_t data_len,
                                         apr_pool_t *result_pool)
{
  svn_fs_x__changes_t *changes = (svn_fs_x__changes_t *)data;

  /* de-serialize sub-structures */
  svn_fs_x__deserialize_string_table(changes, &changes->paths);
  svn_fs_x__deserialize_apr_array(changes, &changes->changes, result_pool);
  svn_fs_x__deserialize_apr_array(changes, &changes->offsets, result_pool);

  /* done */
  *out = changes;

  return SVN_NO_ERROR;
}

svn_error_t *
svn_fs_x__changes_get_list_func(void **out,
                                const void *data,
                                apr_size_t data_len,
                                void *baton,
                                apr_pool_t *pool)
{
  int first;
  int last;
  int i;
  apr_array_header_t *list;

  svn_fs_x__changes_get_list_baton_t *b = baton;
  apr_uint32_t idx = b->sub_item;
  const svn_fs_x__changes_t *container = data;

  /* resolve all the sub-container pointers we need */
  const string_table_t *paths
    = svn_temp_deserializer__ptr(container,
                                 (const void *const *)&container->paths);
  const apr_array_header_t *serialized_offsets
    = svn_temp_deserializer__ptr(container,
                                 (const void *const *)&container->offsets);
  const apr_array_header_t *serialized_changes
    = svn_temp_deserializer__ptr(container,
                                 (const void *const *)&container->changes);
  const int *offsets
    = svn_temp_deserializer__ptr(serialized_offsets,
                              (const void *const *)&serialized_offsets->elts);
  const binary_change_t *changes
    = svn_temp_deserializer__ptr(serialized_changes,
                              (const void *const *)&serialized_changes->elts);

  /* validate index */
  if (idx + 1 >= (apr_size_t)serialized_offsets->nelts)
    return svn_error_createf(SVN_ERR_FS_CONTAINER_INDEX, NULL,
                             _("Changes list index %u exceeds container "
                               "size %d"),
                             (unsigned)idx, serialized_offsets->nelts - 1);

  /* range of changes to return */
  first = offsets[idx];
  last = offsets[idx+1];

  /* Restrict range to the block requested by the BATON.
   * Tell the caller whether we reached the end of the list. */
  first = MIN(first + b->start, last);
  last = MIN(first + SVN_FS_X__CHANGES_BLOCK_SIZE, last);
  *b->eol = last == offsets[idx+1];

  /* construct result */
  list = apr_array_make(pool, last - first, sizeof(svn_fs_x__change_t*));

  for (i = first; i < last; ++i)
    {
      const binary_change_t *binary_change = &changes[i];

      /* convert BINARY_CHANGE into a standard FSX svn_fs_x__change_t */
      svn_fs_x__change_t *change = apr_pcalloc(pool, sizeof(*change));
      change->path.data
        = svn_fs_x__string_table_get_func(paths, binary_change->path,
                                          &change->path.len, pool);

      change->change_kind = (svn_fs_path_change_kind_t)
        ((binary_change->flags & CHANGE_KIND_MASK) >> CHANGE_KIND_SHIFT);
      change->text_mod = (binary_change->flags & CHANGE_TEXT_MOD) != 0;
      change->prop_mod = (binary_change->flags & CHANGE_PROP_MOD) != 0;
      change->node_kind = (svn_node_kind_t)
        ((binary_change->flags & CHANGE_NODE_MASK) >> CHANGE_NODE_SHIFT);

      change->copyfrom_rev = binary_change->copyfrom_rev;
      change->copyfrom_known = TRUE;
      if (SVN_IS_VALID_REVNUM(binary_change->copyfrom_rev))
        change->copyfrom_path
          = svn_fs_x__string_table_get_func(paths,
                                            binary_change->copyfrom_path,
                                            NULL,
                                            pool);

      /* add it to the result */
      APR_ARRAY_PUSH(list, svn_fs_x__change_t*) = change;
    }

  *out = list;

  return SVN_NO_ERROR;
}
