/*
 * Copyright (C) 2012 The Android Open Source Project
 *
 * Licensed 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 <assert.h>
#include <stdlib.h>

#include <sparse/sparse.h>

#include "defs.h"
#include "sparse_file.h"

#include "backed_block.h"
#include "output_file.h"
#include "sparse_defs.h"
#include "sparse_format.h"

struct sparse_file* sparse_file_new(unsigned int block_size, int64_t len) {
  struct sparse_file* s = reinterpret_cast<sparse_file*>(calloc(sizeof(struct sparse_file), 1));
  if (!s) {
    return nullptr;
  }

  s->backed_block_list = backed_block_list_new(block_size);
  if (!s->backed_block_list) {
    free(s);
    return nullptr;
  }

  s->block_size = block_size;
  s->len = len;

  return s;
}

void sparse_file_destroy(struct sparse_file* s) {
  backed_block_list_destroy(s->backed_block_list);
  free(s);
}

int sparse_file_add_data(struct sparse_file* s, void* data, unsigned int len, unsigned int block) {
  return backed_block_add_data(s->backed_block_list, data, len, block);
}

int sparse_file_add_fill(struct sparse_file* s, uint32_t fill_val, unsigned int len,
                         unsigned int block) {
  return backed_block_add_fill(s->backed_block_list, fill_val, len, block);
}

int sparse_file_add_file(struct sparse_file* s, const char* filename, int64_t file_offset,
                         unsigned int len, unsigned int block) {
  return backed_block_add_file(s->backed_block_list, filename, file_offset, len, block);
}

int sparse_file_add_fd(struct sparse_file* s, int fd, int64_t file_offset, unsigned int len,
                       unsigned int block) {
  return backed_block_add_fd(s->backed_block_list, fd, file_offset, len, block);
}
unsigned int sparse_count_chunks(struct sparse_file* s) {
  struct backed_block* bb;
  unsigned int last_block = 0;
  unsigned int chunks = 0;

  for (bb = backed_block_iter_new(s->backed_block_list); bb; bb = backed_block_iter_next(bb)) {
    if (backed_block_block(bb) > last_block) {
      /* If there is a gap between chunks, add a skip chunk */
      chunks++;
    }
    chunks++;
    last_block = backed_block_block(bb) + DIV_ROUND_UP(backed_block_len(bb), s->block_size);
  }
  if (last_block < DIV_ROUND_UP(s->len, s->block_size)) {
    chunks++;
  }

  return chunks;
}

static int sparse_file_write_block(struct output_file* out, struct backed_block* bb) {
  int ret = -EINVAL;

  switch (backed_block_type(bb)) {
    case BACKED_BLOCK_DATA:
      ret = write_data_chunk(out, backed_block_len(bb), backed_block_data(bb));
      break;
    case BACKED_BLOCK_FILE:
      ret = write_file_chunk(out, backed_block_len(bb), backed_block_filename(bb),
                             backed_block_file_offset(bb));
      break;
    case BACKED_BLOCK_FD:
      ret = write_fd_chunk(out, backed_block_len(bb), backed_block_fd(bb),
                           backed_block_file_offset(bb));
      break;
    case BACKED_BLOCK_FILL:
      ret = write_fill_chunk(out, backed_block_len(bb), backed_block_fill_val(bb));
      break;
  }

  return ret;
}

static int write_all_blocks(struct sparse_file* s, struct output_file* out) {
  struct backed_block* bb;
  unsigned int last_block = 0;
  int64_t pad;
  int ret = 0;

  for (bb = backed_block_iter_new(s->backed_block_list); bb; bb = backed_block_iter_next(bb)) {
    if (backed_block_block(bb) > last_block) {
      unsigned int blocks = backed_block_block(bb) - last_block;
      write_skip_chunk(out, (int64_t)blocks * s->block_size);
    }
    ret = sparse_file_write_block(out, bb);
    if (ret) return ret;
    last_block = backed_block_block(bb) + DIV_ROUND_UP(backed_block_len(bb), s->block_size);
  }

  pad = s->len - (int64_t)last_block * s->block_size;
  assert(pad >= 0);
  if (pad > 0) {
    write_skip_chunk(out, pad);
  }

  return 0;
}

int sparse_file_write(struct sparse_file* s, int fd, bool gz, bool sparse, bool crc) {
  int ret;
  int chunks;
  struct output_file* out;

  chunks = sparse_count_chunks(s);
  out = output_file_open_fd(fd, s->block_size, s->len, gz, sparse, chunks, crc);

  if (!out) return -ENOMEM;

  ret = write_all_blocks(s, out);

  output_file_close(out);

  return ret;
}

int sparse_file_callback(struct sparse_file* s, bool sparse, bool crc,
                         int (*write)(void* priv, const void* data, size_t len), void* priv) {
  int ret;
  int chunks;
  struct output_file* out;

  chunks = sparse_count_chunks(s);
  out = output_file_open_callback(write, priv, s->block_size, s->len, false, sparse, chunks, crc);

  if (!out) return -ENOMEM;

  ret = write_all_blocks(s, out);

  output_file_close(out);

  return ret;
}

struct chunk_data {
  void* priv;
  unsigned int block;
  unsigned int nr_blocks;
  int (*write)(void* priv, const void* data, size_t len, unsigned int block, unsigned int nr_blocks);
};

static int foreach_chunk_write(void* priv, const void* data, size_t len) {
  struct chunk_data* chk = reinterpret_cast<chunk_data*>(priv);

  return chk->write(chk->priv, data, len, chk->block, chk->nr_blocks);
}

int sparse_file_foreach_chunk(struct sparse_file* s, bool sparse, bool crc,
                              int (*write)(void* priv, const void* data, size_t len,
                                           unsigned int block, unsigned int nr_blocks),
                              void* priv) {
  int ret = 0;
  int chunks;
  struct chunk_data chk;
  struct output_file* out;
  struct backed_block* bb;

  chk.priv = priv;
  chk.write = write;
  chk.block = chk.nr_blocks = 0;
  chunks = sparse_count_chunks(s);
  out = output_file_open_callback(foreach_chunk_write, &chk, s->block_size, s->len, false, sparse,
                                  chunks, crc);

  if (!out) return -ENOMEM;

  for (bb = backed_block_iter_new(s->backed_block_list); bb; bb = backed_block_iter_next(bb)) {
    chk.block = backed_block_block(bb);
    chk.nr_blocks = (backed_block_len(bb) - 1) / s->block_size + 1;
    ret = sparse_file_write_block(out, bb);
    if (ret) return ret;
  }

  output_file_close(out);

  return ret;
}

static int out_counter_write(void* priv, const void* data __unused, size_t len) {
  int64_t* count = reinterpret_cast<int64_t*>(priv);
  *count += len;
  return 0;
}

int64_t sparse_file_len(struct sparse_file* s, bool sparse, bool crc) {
  int ret;
  int chunks = sparse_count_chunks(s);
  int64_t count = 0;
  struct output_file* out;

  out = output_file_open_callback(out_counter_write, &count, s->block_size, s->len, false, sparse,
                                  chunks, crc);
  if (!out) {
    return -1;
  }

  ret = write_all_blocks(s, out);

  output_file_close(out);

  if (ret < 0) {
    return -1;
  }

  return count;
}

unsigned int sparse_file_block_size(struct sparse_file* s) {
  return s->block_size;
}

static struct backed_block* move_chunks_up_to_len(struct sparse_file* from, struct sparse_file* to,
                                                  unsigned int len) {
  int64_t count = 0;
  struct output_file* out_counter;
  struct backed_block* last_bb = nullptr;
  struct backed_block* bb;
  struct backed_block* start;
  unsigned int last_block = 0;
  int64_t file_len = 0;
  int ret;

  /*
   * overhead is sparse file header, the potential end skip
   * chunk and crc chunk.
   */
  int overhead = sizeof(sparse_header_t) + 2 * sizeof(chunk_header_t) + sizeof(uint32_t);
  len -= overhead;

  start = backed_block_iter_new(from->backed_block_list);
  out_counter = output_file_open_callback(out_counter_write, &count, to->block_size, to->len, false,
                                          true, 0, false);
  if (!out_counter) {
    return nullptr;
  }

  for (bb = start; bb; bb = backed_block_iter_next(bb)) {
    count = 0;
    if (backed_block_block(bb) > last_block) count += sizeof(chunk_header_t);
    last_block = backed_block_block(bb) + DIV_ROUND_UP(backed_block_len(bb), to->block_size);

    /* will call out_counter_write to update count */
    ret = sparse_file_write_block(out_counter, bb);
    if (ret) {
      bb = nullptr;
      goto out;
    }
    if (file_len + count > len) {
      /*
       * If the remaining available size is more than 1/8th of the
       * requested size, split the chunk.  Results in sparse files that
       * are at least 7/8ths of the requested size
       */
      file_len += sizeof(chunk_header_t);
      if (!last_bb || (len - file_len > (len / 8))) {
        backed_block_split(from->backed_block_list, bb, len - file_len);
        last_bb = bb;
      }
      goto move;
    }
    file_len += count;
    last_bb = bb;
  }

move:
  backed_block_list_move(from->backed_block_list, to->backed_block_list, start, last_bb);

out:
  output_file_close(out_counter);

  return bb;
}

int sparse_file_resparse(struct sparse_file* in_s, unsigned int max_len, struct sparse_file** out_s,
                         int out_s_count) {
  struct backed_block* bb;
  struct sparse_file* s;
  struct sparse_file* tmp;
  int c = 0;

  tmp = sparse_file_new(in_s->block_size, in_s->len);
  if (!tmp) {
    return -ENOMEM;
  }

  do {
    s = sparse_file_new(in_s->block_size, in_s->len);

    bb = move_chunks_up_to_len(in_s, s, max_len);

    if (c < out_s_count) {
      out_s[c] = s;
    } else {
      backed_block_list_move(s->backed_block_list, tmp->backed_block_list, nullptr, nullptr);
      sparse_file_destroy(s);
    }
    c++;
  } while (bb);

  backed_block_list_move(tmp->backed_block_list, in_s->backed_block_list, nullptr, nullptr);

  sparse_file_destroy(tmp);

  return c;
}

void sparse_file_verbose(struct sparse_file* s) {
  s->verbose = true;
}
