/* load-index-cmd.c -- implements the dump-index sub-command.
 *
 * ====================================================================
 *    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_ctype.h"
#include "svn_dirent_uri.h"
#include "svn_io.h"
#include "svn_pools.h"

#include "private/svn_fs_fs_private.h"
#include "private/svn_sorts_private.h"

#include "svn_private_config.h"

#include "svnfsfs.h"

/* Map svn_fs_fs__p2l_entry_t.type to C string. */
static const char *item_type_str[]
  = {"none", "frep", "drep", "fprop", "dprop", "node", "chgs", "rep"};

/* Reverse lookup in ITEM_TYPE_STR: Set *TYPE to the index that contains STR.
 * Return an error for invalid strings. */
static svn_error_t *
str_to_item_type(unsigned *type,
                 const char *str)
{
  unsigned i;
  for (i = 0; i < sizeof(item_type_str) / sizeof(item_type_str[0]); ++i)
    if (strcmp(item_type_str[i], str) == 0)
      {
        *type = i;
        return SVN_NO_ERROR;
      }

  return svn_error_createf(SVN_ERR_BAD_TOKEN, NULL,
                           _("Unknown item type '%s'"), str);
}

/* Parse the string given as const char * at IDX in TOKENS and return its
 * value in *VALUE_P.  Assume that the string an integer with base RADIX.
 * Check for index overflows and non-hex chars.
 */
static svn_error_t *
token_to_i64(apr_int64_t *value_p,
             apr_array_header_t *tokens,
             int idx,
             int radix)
{
  const char *hex;
  char *end;
  apr_int64_t value;

  /* Tell the user when there is not enough information. */
  SVN_ERR_ASSERT(idx >= 0);
  if (tokens->nelts <= idx)
    return svn_error_createf(SVN_ERR_INVALID_INPUT, NULL,
                             _("%i columns needed, %i provided"),
                             idx + 1, tokens->nelts);

  /* hex -> int conversion */
  hex = APR_ARRAY_IDX(tokens, idx, const char *);
  value = apr_strtoi64(hex, &end, radix);

  /* Has the whole token be parsed without error? */
  if (errno || *end != '\0')
    return svn_error_createf(SVN_ERR_INVALID_INPUT, NULL,
                             _("%s is not a value HEX string"), hex);

  *value_p = value;
  return SVN_NO_ERROR;
}

/* Parse the P2L entry given as space separated values in LINE and return it
 * in *ENTRY.  Ignore extra columns.  Allocate the result in RESULT_POOL and
 * use SCRATCH_POOL for temporaries.
 */
static svn_error_t *
parse_index_line(svn_fs_fs__p2l_entry_t **entry,
                 svn_stringbuf_t *line,
                 apr_pool_t *result_pool,
                 apr_pool_t *scratch_pool)
{
  apr_array_header_t *tokens = svn_cstring_split(line->data, " ", TRUE,
                                                 scratch_pool);
  svn_fs_fs__p2l_entry_t *result = apr_pcalloc(result_pool, sizeof(*result));
  apr_int64_t value;

  /* Parse the hex columns. */
  SVN_ERR(token_to_i64(&value, tokens, 0, 16));
  result->offset = (apr_off_t)value;
  SVN_ERR(token_to_i64(&value, tokens, 1, 16));
  result->size = (apr_off_t)value;

  /* Parse the rightmost column that we care of. */
  SVN_ERR(token_to_i64(&value, tokens, 4, 10));
  result->item.number = (apr_uint64_t)value;

  /* We now know that there were at least 5 columns.
   * Parse the non-hex columns without index check. */
  SVN_ERR(str_to_item_type(&result->type,
                           APR_ARRAY_IDX(tokens, 2, const char *)));
  SVN_ERR(svn_revnum_parse(&result->item.revision,
                           APR_ARRAY_IDX(tokens, 3, const char *), NULL));

  *entry = result;
  return SVN_NO_ERROR;
}

/* Parse the space separated P2L index table from INPUT, one entry per line.
 * Rewrite the respective index files in PATH.  Allocate from POOL. */
static svn_error_t *
load_index(const char *path,
           svn_stream_t *input,
           apr_pool_t *pool)
{
  svn_fs_t *fs;
  svn_revnum_t revision = SVN_INVALID_REVNUM;
  apr_array_header_t *entries = apr_array_make(pool, 16, sizeof(void*));
  apr_pool_t *iterpool = svn_pool_create(pool);
  svn_fs_fs__ioctl_load_index_input_t ioctl_input = {0};

  /* Check repository type and open it. */
  SVN_ERR(open_fs(&fs, path, pool));

  while (TRUE)
    {
      svn_stringbuf_t *line;
      svn_fs_fs__p2l_entry_t *entry;
      svn_boolean_t eol;

      /* Get the next line from the input and stop if there is none. */
      svn_pool_clear(iterpool);
      SVN_ERR(svn_stream_readline(input, &line, "\n", &eol, iterpool));
      if (eol)
        break;

      /* Skip header line(s).  They contain the sub-string [Ss]tart. */
      if (strstr(line->data, "tart"))
        continue;

      /* Ignore empty lines (mostly trailing ones but we don't really care).
       */
      svn_stringbuf_strip_whitespace(line);
      if (line->len == 0)
        continue;

      /* Parse the entry and append it to ENTRIES. */
      SVN_ERR(parse_index_line(&entry, line, pool, iterpool));
      APR_ARRAY_PUSH(entries, svn_fs_fs__p2l_entry_t *) = entry;

      /* There should be at least one item that is not empty.
       * Get a revision from (probably inside) the respective shard. */
      if (   revision == SVN_INVALID_REVNUM
          && entry->item.revision != SVN_INVALID_REVNUM)
        revision = entry->item.revision;
    }

  /* Rewrite the indexes. */
  ioctl_input.revision = revision;
  ioctl_input.entries = entries;
  SVN_ERR(svn_fs_ioctl(fs, SVN_FS_FS__IOCTL_LOAD_INDEX, &ioctl_input, NULL,
                       NULL, NULL, pool, pool));
  svn_pool_destroy(iterpool);

  return SVN_NO_ERROR;
}

/* This implements `svn_opt_subcommand_t'. */
svn_error_t *
subcommand__load_index(apr_getopt_t *os, void *baton, apr_pool_t *pool)
{
  svnfsfs__opt_state *opt_state = baton;
  svn_stream_t *input;

  SVN_ERR(svn_stream_for_stdin2(&input, TRUE, pool));
  SVN_ERR(load_index(opt_state->repository_path, input, pool));

  return SVN_NO_ERROR;
}
