/*
 * 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.
 */

#include "git2.h"
#include "smart.h"
#include "git2/cred_helpers.h"

static int git_cred_ssh_key_type_new(
	git_cred **cred,
	const char *username,
	const char *publickey,
	const char *privatekey,
	const char *passphrase,
	git_credtype_t credtype);

int git_cred_has_username(git_cred *cred)
{
	if (cred->credtype == GIT_CREDTYPE_DEFAULT)
		return 0;

	return 1;
}

const char *git_cred__username(git_cred *cred)
{
	switch (cred->credtype) {
	case GIT_CREDTYPE_USERNAME:
	{
		git_cred_username *c = (git_cred_username *) cred;
		return c->username;
	}
	case GIT_CREDTYPE_USERPASS_PLAINTEXT:
	{
		git_cred_userpass_plaintext *c = (git_cred_userpass_plaintext *) cred;
		return c->username;
	}
	case GIT_CREDTYPE_SSH_KEY:
	case GIT_CREDTYPE_SSH_MEMORY:
	{
		git_cred_ssh_key *c = (git_cred_ssh_key *) cred;
		return c->username;
	}
	case GIT_CREDTYPE_SSH_CUSTOM:
	{
		git_cred_ssh_custom *c = (git_cred_ssh_custom *) cred;
		return c->username;
	}
	case GIT_CREDTYPE_SSH_INTERACTIVE:
	{
		git_cred_ssh_interactive *c = (git_cred_ssh_interactive *) cred;
		return c->username;
	}

	default:
		return NULL;
	}
}

static void plaintext_free(struct git_cred *cred)
{
	git_cred_userpass_plaintext *c = (git_cred_userpass_plaintext *)cred;

	git__free(c->username);

	/* Zero the memory which previously held the password */
	if (c->password) {
		size_t pass_len = strlen(c->password);
		git__memzero(c->password, pass_len);
		git__free(c->password);
	}

	git__free(c);
}

int git_cred_userpass_plaintext_new(
	git_cred **cred,
	const char *username,
	const char *password)
{
	git_cred_userpass_plaintext *c;

	assert(cred && username && password);

	c = git__malloc(sizeof(git_cred_userpass_plaintext));
	GITERR_CHECK_ALLOC(c);

	c->parent.credtype = GIT_CREDTYPE_USERPASS_PLAINTEXT;
	c->parent.free = plaintext_free;
	c->username = git__strdup(username);

	if (!c->username) {
		git__free(c);
		return -1;
	}

	c->password = git__strdup(password);

	if (!c->password) {
		git__free(c->username);
		git__free(c);
		return -1;
	}

	*cred = &c->parent;
	return 0;
}

static void ssh_key_free(struct git_cred *cred)
{
	git_cred_ssh_key *c =
		(git_cred_ssh_key *)cred;

	git__free(c->username);

	if (c->privatekey) {
		/* Zero the memory which previously held the private key */
		size_t key_len = strlen(c->privatekey);
		git__memzero(c->privatekey, key_len);
		git__free(c->privatekey);
	}

	if (c->passphrase) {
		/* Zero the memory which previously held the passphrase */
		size_t pass_len = strlen(c->passphrase);
		git__memzero(c->passphrase, pass_len);
		git__free(c->passphrase);
	}

	if (c->publickey) {
		/* Zero the memory which previously held the public key */
		size_t key_len = strlen(c->publickey);
		git__memzero(c->publickey, key_len);
		git__free(c->publickey);
	}

	git__free(c);
}

static void ssh_interactive_free(struct git_cred *cred)
{
	git_cred_ssh_interactive *c = (git_cred_ssh_interactive *)cred;

	git__free(c->username);

	git__free(c);
}

static void ssh_custom_free(struct git_cred *cred)
{
	git_cred_ssh_custom *c = (git_cred_ssh_custom *)cred;

	git__free(c->username);

	if (c->publickey) {
		/* Zero the memory which previously held the publickey */
		size_t key_len = strlen(c->publickey);
		git__memzero(c->publickey, key_len);
		git__free(c->publickey);
	}

	git__free(c);
}

static void default_free(struct git_cred *cred)
{
	git_cred_default *c = (git_cred_default *)cred;

	git__free(c);
}

static void username_free(struct git_cred *cred)
{
	git__free(cred);
}

int git_cred_ssh_key_new(
	git_cred **cred,
	const char *username,
	const char *publickey,
	const char *privatekey,
	const char *passphrase)
{
	return git_cred_ssh_key_type_new(
		cred,
		username,
		publickey,
		privatekey,
		passphrase,
		GIT_CREDTYPE_SSH_KEY);
}

int git_cred_ssh_key_memory_new(
	git_cred **cred,
	const char *username,
	const char *publickey,
	const char *privatekey,
	const char *passphrase)
{
#ifdef GIT_SSH_MEMORY_CREDENTIALS
	return git_cred_ssh_key_type_new(
		cred,
		username,
		publickey,
		privatekey,
		passphrase,
		GIT_CREDTYPE_SSH_MEMORY);
#else
	GIT_UNUSED(cred);
	GIT_UNUSED(username);
	GIT_UNUSED(publickey);
	GIT_UNUSED(privatekey);
	GIT_UNUSED(passphrase);

	giterr_set(GITERR_INVALID,
		"This version of libgit2 was not built with ssh memory credentials.");
	return -1;
#endif
}

static int git_cred_ssh_key_type_new(
	git_cred **cred,
	const char *username,
	const char *publickey,
	const char *privatekey,
	const char *passphrase,
	git_credtype_t credtype)
{
	git_cred_ssh_key *c;

	assert(username && cred && privatekey);

	c = git__calloc(1, sizeof(git_cred_ssh_key));
	GITERR_CHECK_ALLOC(c);

	c->parent.credtype = credtype;
	c->parent.free = ssh_key_free;

	c->username = git__strdup(username);
	GITERR_CHECK_ALLOC(c->username);

	c->privatekey = git__strdup(privatekey);
	GITERR_CHECK_ALLOC(c->privatekey);

	if (publickey) {
		c->publickey = git__strdup(publickey);
		GITERR_CHECK_ALLOC(c->publickey);
	}

	if (passphrase) {
		c->passphrase = git__strdup(passphrase);
		GITERR_CHECK_ALLOC(c->passphrase);
	}

	*cred = &c->parent;
	return 0;
}

int git_cred_ssh_interactive_new(
	git_cred **out,
	const char *username,
	git_cred_ssh_interactive_callback prompt_callback,
	void *payload)
{
	git_cred_ssh_interactive *c;

	assert(out && username && prompt_callback);

	c = git__calloc(1, sizeof(git_cred_ssh_interactive));
	GITERR_CHECK_ALLOC(c);

	c->parent.credtype = GIT_CREDTYPE_SSH_INTERACTIVE;
	c->parent.free = ssh_interactive_free;

	c->username = git__strdup(username);
	GITERR_CHECK_ALLOC(c->username);

	c->prompt_callback = prompt_callback;
	c->payload = payload;

	*out = &c->parent;
	return 0;
}

int git_cred_ssh_key_from_agent(git_cred **cred, const char *username) {
	git_cred_ssh_key *c;

	assert(username && cred);

	c = git__calloc(1, sizeof(git_cred_ssh_key));
	GITERR_CHECK_ALLOC(c);

	c->parent.credtype = GIT_CREDTYPE_SSH_KEY;
	c->parent.free = ssh_key_free;

	c->username = git__strdup(username);
	GITERR_CHECK_ALLOC(c->username);

	c->privatekey = NULL;

	*cred = &c->parent;
	return 0;
}

int git_cred_ssh_custom_new(
	git_cred **cred,
	const char *username,
	const char *publickey,
	size_t publickey_len,
	git_cred_sign_callback sign_callback,
	void *payload)
{
	git_cred_ssh_custom *c;

	assert(username && cred);

	c = git__calloc(1, sizeof(git_cred_ssh_custom));
	GITERR_CHECK_ALLOC(c);

	c->parent.credtype = GIT_CREDTYPE_SSH_CUSTOM;
	c->parent.free = ssh_custom_free;

	c->username = git__strdup(username);
	GITERR_CHECK_ALLOC(c->username);

	if (publickey_len > 0) {
		c->publickey = git__malloc(publickey_len);
		GITERR_CHECK_ALLOC(c->publickey);

		memcpy(c->publickey, publickey, publickey_len);
	}

	c->publickey_len = publickey_len;
	c->sign_callback = sign_callback;
	c->payload = payload;

	*cred = &c->parent;
	return 0;
}

int git_cred_default_new(git_cred **cred)
{
	git_cred_default *c;

	assert(cred);

	c = git__calloc(1, sizeof(git_cred_default));
	GITERR_CHECK_ALLOC(c);

	c->credtype = GIT_CREDTYPE_DEFAULT;
	c->free = default_free;

	*cred = c;
	return 0;
}

int git_cred_username_new(git_cred **cred, const char *username)
{
	git_cred_username *c;
	size_t len, allocsize;

	assert(cred);

	len = strlen(username);

	GITERR_CHECK_ALLOC_ADD(&allocsize, sizeof(git_cred_username), len);
	GITERR_CHECK_ALLOC_ADD(&allocsize, allocsize, 1);
	c = git__malloc(allocsize);
	GITERR_CHECK_ALLOC(c);

	c->parent.credtype = GIT_CREDTYPE_USERNAME;
	c->parent.free = username_free;
	memcpy(c->username, username, len + 1);

	*cred = (git_cred *) c;
	return 0;
}

void git_cred_free(git_cred *cred)
{
	if (!cred)
		return;

	cred->free(cred);
}
