/*
 * This file is part of the Poliqarp suite.
 * 
 * Copyright (C) 2009 by Instytut Podstaw Informatyki Polskiej
 * Akademii Nauk (IPI PAN; Institute of Computer Science, Polish
 * Academy of Sciences; cf. www.ipipan.waw.pl).  All rights reserved.
 * 
 * This file may be distributed and/or modified under the terms of the
 * GNU General Public License version 2 as published by the Free Software
 * Foundation and appearing in the file gpl.txt included in the packaging
 * of this file.  (See http://www.gnu.org/licenses/translations.html for
 * unofficial translations.)
 * 
 * A commercial license is available from IPI PAN (contact
 * Michal.Ciesiolka@ipipan.waw.pl or ipi@ipipan.waw.pl for more
 * information).  Licensees holding a valid commercial license from IPI
 * PAN may use this file in accordance with that license.
 * 
 * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING
 * THE WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 * PURPOSE.
 */

#ifndef BPNG_CORPUS_H
#define BPNG_CORPUS_H 1

#include <stdio.h>

#include <bp/ng/meta-key.h>
#include <bp/ng/binary-pool.h>
#include <bp/ng/list.h>
#include <bp/ng/segment.h>
#include <foostring/foostring.h>

/**
 * Data for building a binary corpus.
 */
struct corpus {
   const char *base_name;
   size_t nsegments;
   size_t nmeta;
   struct binary_pool tag_pool;
   struct binary_pool orth_pool;
   struct binary_pool dis_base_pool;
   struct binary_pool amb_base_pool;
   struct binary_pool dis_interp_pool;
   struct binary_pool amb_interp_pool;
   struct binary_pool subdocument_pool;
   struct binary_pool meta_key_pool;
   struct binary_pool meta_value_pool;
   FILE *fp_corpus;
   FILE *fp_meta;
   FILE *fp_documents;
   FILE *fp_meta_types;
   FILE *fp_cdf;
   struct list subdocument_types;
};

/**
 * Data for building a document within a corpus.
 */

struct corpus_document {
   struct corpus *corpus;
   size_t nsegments;
   size_t nmeta;
   struct list subdocument_ranges;
   struct list subdocument_stack;
   string_t segment_buffer;
   string_t meta_buffer;
};

/**
 * Initialize the corpus structure.
 *
 * @note Results of incremental build are typically suboptimal!
 */
void corpus_create(struct corpus *, const char *base, bool incremental);

/**
 * Destroy the corpus structure.
 */
void corpus_destroy(struct corpus *);

/**
 * Add the meta key to the corpus.
 */
void corpus_add_meta_key(struct corpus *, const struct meta_key *);

/**
 * Commit all the meta keys to the binary corpus. No further meta key additions
 * are allowed afterwards.
 */
void corpus_commit_meta_keys(struct corpus *);

/**
 * Mark the start of a document.
 */
struct corpus_document *corpus_start_document(struct corpus *);

/**
 * Mark the end of a document.
 */
int corpus_end_document(struct corpus_document *, bool commit);

/**
 * Commit the dictionaries and the CDF file to the binary corpus.
 *
 * No further changes to the corpus are allowed afterwards.
 */
void corpus_commit(struct corpus *);

/**
 * Add the segment to the corpus.
 *
 * @return 0 in case of success, -1 in case of error
 */
int corpus_add_segment(struct corpus_document *, const struct segment *);

/**
 * Mark the beginning of a subdocument.
 *
 * @param name of the subdocument, or NULL
 */
void corpus_push_subdocument(struct corpus_document *, const char *name);

/**
 * Mark the end of a subdocument.
 */
void corpus_pop_subdocument(struct corpus_document *);

/**
 * Add the key-value pair to the corpus.
 */
void corpus_add_meta_value(struct corpus_document *, const struct meta_key *,
   const char *value);

/**
 * Commit all the meta key-value pairs to the binary corpus. No further meta
 * key-value additions are allowed afterwards.
 */
void corpus_commit_meta_keys(struct corpus *);

#endif
