/*
Copyright 2020 Google LLC

Use of this source code is governed by a BSD-style
license that can be found in the LICENSE file or at
https://developers.google.com/open-source/licenses/bsd
*/

#include "iter.h"

#include "system.h"

#include "block.h"
#include "generic.h"
#include "constants.h"
#include "reader.h"
#include "reftable-error.h"

static void filtering_ref_iterator_close(void *iter_arg)
{
	struct filtering_ref_iterator *fri = iter_arg;
	strbuf_release(&fri->oid);
	reftable_iterator_destroy(&fri->it);
}

static int filtering_ref_iterator_seek(void *iter_arg,
				       struct reftable_record *want)
{
	struct filtering_ref_iterator *fri = iter_arg;
	return iterator_seek(&fri->it, want);
}

static int filtering_ref_iterator_next(void *iter_arg,
				       struct reftable_record *rec)
{
	struct filtering_ref_iterator *fri = iter_arg;
	struct reftable_ref_record *ref = &rec->u.ref;
	int err = 0;
	while (1) {
		err = reftable_iterator_next_ref(&fri->it, ref);
		if (err != 0) {
			break;
		}

		if (fri->double_check) {
			struct reftable_iterator it = { NULL };

			reftable_table_init_ref_iter(&fri->tab, &it);

			err = reftable_iterator_seek_ref(&it, ref->refname);
			if (err == 0)
				err = reftable_iterator_next_ref(&it, ref);

			reftable_iterator_destroy(&it);

			if (err < 0) {
				break;
			}

			if (err > 0) {
				continue;
			}
		}

		if (ref->value_type == REFTABLE_REF_VAL2 &&
		    (!memcmp(fri->oid.buf, ref->value.val2.target_value,
			     fri->oid.len) ||
		     !memcmp(fri->oid.buf, ref->value.val2.value,
			     fri->oid.len)))
			return 0;

		if (ref->value_type == REFTABLE_REF_VAL1 &&
		    !memcmp(fri->oid.buf, ref->value.val1, fri->oid.len)) {
			return 0;
		}
	}

	reftable_ref_record_release(ref);
	return err;
}

static struct reftable_iterator_vtable filtering_ref_iterator_vtable = {
	.seek = &filtering_ref_iterator_seek,
	.next = &filtering_ref_iterator_next,
	.close = &filtering_ref_iterator_close,
};

void iterator_from_filtering_ref_iterator(struct reftable_iterator *it,
					  struct filtering_ref_iterator *fri)
{
	assert(!it->ops);
	it->iter_arg = fri;
	it->ops = &filtering_ref_iterator_vtable;
}

static void indexed_table_ref_iter_close(void *p)
{
	struct indexed_table_ref_iter *it = p;
	block_iter_close(&it->cur);
	reftable_block_done(&it->block_reader.block);
	reftable_free(it->offsets);
	strbuf_release(&it->oid);
}

static int indexed_table_ref_iter_next_block(struct indexed_table_ref_iter *it)
{
	uint64_t off;
	int err = 0;
	if (it->offset_idx == it->offset_len) {
		it->is_finished = 1;
		return 1;
	}

	reftable_block_done(&it->block_reader.block);

	off = it->offsets[it->offset_idx++];
	err = reader_init_block_reader(it->r, &it->block_reader, off,
				       BLOCK_TYPE_REF);
	if (err < 0) {
		return err;
	}
	if (err > 0) {
		/* indexed block does not exist. */
		return REFTABLE_FORMAT_ERROR;
	}
	block_iter_seek_start(&it->cur, &it->block_reader);
	return 0;
}

static int indexed_table_ref_iter_seek(void *p, struct reftable_record *want)
{
	BUG("seeking indexed table is not supported");
	return -1;
}

static int indexed_table_ref_iter_next(void *p, struct reftable_record *rec)
{
	struct indexed_table_ref_iter *it = p;
	struct reftable_ref_record *ref = &rec->u.ref;

	while (1) {
		int err = block_iter_next(&it->cur, rec);
		if (err < 0) {
			return err;
		}

		if (err > 0) {
			err = indexed_table_ref_iter_next_block(it);
			if (err < 0) {
				return err;
			}

			if (it->is_finished) {
				return 1;
			}
			continue;
		}
		/* BUG */
		if (!memcmp(it->oid.buf, ref->value.val2.target_value,
			    it->oid.len) ||
		    !memcmp(it->oid.buf, ref->value.val2.value, it->oid.len)) {
			return 0;
		}
	}
}

int new_indexed_table_ref_iter(struct indexed_table_ref_iter **dest,
			       struct reftable_reader *r, uint8_t *oid,
			       int oid_len, uint64_t *offsets, int offset_len)
{
	struct indexed_table_ref_iter empty = INDEXED_TABLE_REF_ITER_INIT;
	struct indexed_table_ref_iter *itr = reftable_calloc(1, sizeof(*itr));
	int err = 0;

	*itr = empty;
	itr->r = r;
	strbuf_add(&itr->oid, oid, oid_len);

	itr->offsets = offsets;
	itr->offset_len = offset_len;

	err = indexed_table_ref_iter_next_block(itr);
	if (err < 0) {
		reftable_free(itr);
	} else {
		*dest = itr;
	}
	return err;
}

static struct reftable_iterator_vtable indexed_table_ref_iter_vtable = {
	.seek = &indexed_table_ref_iter_seek,
	.next = &indexed_table_ref_iter_next,
	.close = &indexed_table_ref_iter_close,
};

void iterator_from_indexed_table_ref_iter(struct reftable_iterator *it,
					  struct indexed_table_ref_iter *itr)
{
	assert(!it->ops);
	it->iter_arg = itr;
	it->ops = &indexed_table_ref_iter_vtable;
}
