/*
 * Copyright (C) the libgit2 contributors. All rights reserved.
 *
 * This file is part of libgit2, distributed under the GNU GPL v2 with
 * a Linking Exception. For full terms see the included COPYING file.
 */
#ifndef INCLUDE_attr_file_h__
#define INCLUDE_attr_file_h__

#include "git2/oid.h"
#include "git2/attr.h"
#include "vector.h"
#include "pool.h"
#include "buffer.h"
#include "fileops.h"

#define GIT_ATTR_FILE			".gitattributes"
#define GIT_ATTR_FILE_INREPO	"attributes"
#define GIT_ATTR_FILE_SYSTEM	"gitattributes"
#define GIT_ATTR_FILE_XDG		"attributes"

#define GIT_ATTR_FNMATCH_NEGATIVE	(1U << 0)
#define GIT_ATTR_FNMATCH_DIRECTORY	(1U << 1)
#define GIT_ATTR_FNMATCH_FULLPATH	(1U << 2)
#define GIT_ATTR_FNMATCH_MACRO		(1U << 3)
#define GIT_ATTR_FNMATCH_IGNORE		(1U << 4)
#define GIT_ATTR_FNMATCH_HASWILD	(1U << 5)
#define GIT_ATTR_FNMATCH_ALLOWSPACE	(1U << 6)
#define GIT_ATTR_FNMATCH_ICASE		(1U << 7)
#define GIT_ATTR_FNMATCH_MATCH_ALL	(1U << 8)
#define GIT_ATTR_FNMATCH_ALLOWNEG   (1U << 9)
#define GIT_ATTR_FNMATCH_ALLOWMACRO (1U << 10)
#define GIT_ATTR_FNMATCH_LEADINGDIR (1U << 11)
#define GIT_ATTR_FNMATCH_NOLEADINGDIR (1U << 12)

#define GIT_ATTR_FNMATCH__INCOMING \
	(GIT_ATTR_FNMATCH_ALLOWSPACE | GIT_ATTR_FNMATCH_ALLOWNEG | \
	 GIT_ATTR_FNMATCH_ALLOWMACRO | GIT_ATTR_FNMATCH_NOLEADINGDIR)

typedef enum {
	GIT_ATTR_FILE__IN_MEMORY   = 0,
	GIT_ATTR_FILE__FROM_FILE   = 1,
	GIT_ATTR_FILE__FROM_INDEX  = 2,

	GIT_ATTR_FILE_NUM_SOURCES  = 3
} git_attr_file_source;

extern const char *git_attr__true;
extern const char *git_attr__false;
extern const char *git_attr__unset;

typedef struct {
	char *pattern;
	size_t length;
	char *containing_dir;
	size_t containing_dir_length;
	unsigned int flags;
} git_attr_fnmatch;

typedef struct {
	git_attr_fnmatch match;
	git_vector assigns;		/* vector of <git_attr_assignment*> */
} git_attr_rule;

typedef struct {
	git_refcount unused;
	const char *name;
	uint32_t name_hash;
} git_attr_name;

typedef struct {
	git_refcount rc;		/* for macros */
	char *name;
	uint32_t name_hash;
	const char *value;
} git_attr_assignment;

typedef struct git_attr_file_entry git_attr_file_entry;

typedef struct {
	git_refcount rc;
	git_mutex lock;
	git_attr_file_entry *entry;
	git_attr_file_source source;
	git_vector rules;			/* vector of <rule*> or <fnmatch*> */
	git_pool pool;
	unsigned int nonexistent:1;
	int session_key;
	union {
		git_oid oid;
		git_futils_filestamp stamp;
	} cache_data;
} git_attr_file;

struct git_attr_file_entry {
	git_attr_file *file[GIT_ATTR_FILE_NUM_SOURCES];
	const char *path; /* points into fullpath */
	char fullpath[GIT_FLEX_ARRAY];
};

typedef struct {
	git_buf  full;
	char    *path;
	char    *basename;
	int      is_dir;
} git_attr_path;

/* A git_attr_session can provide an "instance" of reading, to prevent cache
 * invalidation during a single operation instance (like checkout).
 */

typedef struct {
	int key;
	unsigned int init_setup:1,
		init_sysdir:1;
	git_buf sysdir;
	git_buf tmp;
} git_attr_session;

extern int git_attr_session__init(git_attr_session *attr_session, git_repository *repo);
extern void git_attr_session__free(git_attr_session *session);

extern int git_attr_get_many_with_session(
	const char **values_out,
	git_repository *repo,
	git_attr_session *attr_session,
	uint32_t flags,
	const char *path,
	size_t num_attr,
	const char **names);

typedef int (*git_attr_file_parser)(
	git_repository *repo,
	git_attr_file *file,
	const char *data);

/*
 * git_attr_file API
 */

int git_attr_file__new(
	git_attr_file **out,
	git_attr_file_entry *entry,
	git_attr_file_source source);

void git_attr_file__free(git_attr_file *file);

int git_attr_file__load(
	git_attr_file **out,
	git_repository *repo,
	git_attr_session *attr_session,
	git_attr_file_entry *ce,
	git_attr_file_source source,
	git_attr_file_parser parser);

int git_attr_file__load_standalone(
	git_attr_file **out, const char *path);

int git_attr_file__out_of_date(
	git_repository *repo, git_attr_session *session, git_attr_file *file);

int git_attr_file__parse_buffer(
	git_repository *repo, git_attr_file *attrs, const char *data);

int git_attr_file__clear_rules(
	git_attr_file *file, bool need_lock);

int git_attr_file__lookup_one(
	git_attr_file *file,
	git_attr_path *path,
	const char *attr,
	const char **value);

/* loop over rules in file from bottom to top */
#define git_attr_file__foreach_matching_rule(file, path, iter, rule)	\
	git_vector_rforeach(&(file)->rules, (iter), (rule)) \
		if (git_attr_rule__match((rule), (path)))

uint32_t git_attr_file__name_hash(const char *name);


/*
 * other utilities
 */

extern int git_attr_fnmatch__parse(
	git_attr_fnmatch *spec,
	git_pool *pool,
	const char *source,
	const char **base);

extern bool git_attr_fnmatch__match(
	git_attr_fnmatch *rule,
	git_attr_path *path);

extern void git_attr_rule__free(git_attr_rule *rule);

extern bool git_attr_rule__match(
	git_attr_rule *rule,
	git_attr_path *path);

extern git_attr_assignment *git_attr_rule__lookup_assignment(
	git_attr_rule *rule, const char *name);

typedef enum { GIT_DIR_FLAG_TRUE = 1, GIT_DIR_FLAG_FALSE = 0, GIT_DIR_FLAG_UNKNOWN = -1 } git_dir_flag;

extern int git_attr_path__init(
	git_attr_path *info, const char *path, const char *base, git_dir_flag is_dir);

extern void git_attr_path__free(git_attr_path *info);

extern int git_attr_assignment__parse(
	git_repository *repo, /* needed to expand macros */
	git_pool *pool,
	git_vector *assigns,
	const char **scan);

#endif
