/*
 *
 *  Copyright (C) 2021 Andrew Gegg
 *
 * 	This file is part of the Gardeners Notebook application
 *
 *  The Gardeners Notebook application is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation, either version 3 of the License, or
 *  (at your option) any later version.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *   You should have received a copy of the GNU General Public License
 *  along with this program.  If not, see <http://www.gnu.org/licenses/gpl.html>.
 *
 *
 */

package uk.co.gardennotebook.spi;

import java.time.LocalDate;
import java.util.List;

/**
 *	Free text diary entries not connected to any specific plant, pest, etc.
 *
 *	@author	Andy Gegg
 *	@version	3.0.0
 *	@since	1.0
 */
public interface IJournalBuilder
{
    /**
     *	give the (new) value of date
     *
     *	@param	newVal	the new value
     *	@return	this Builder
     */
    public IJournalBuilder date(LocalDate newVal);

    /**
     *	give the (new) value of title
     *
     *	@param	newVal	the new value
     *	@return	this Builder
     */
    public IJournalBuilder title(String newVal);

    /**
     *	give the (new) value of description
     *
     *	@param	newVal	the new value
     *	@return	this Builder
     */
    public IJournalBuilder description(String newVal);

    /**
     *	Add this value as a comment; may be called multiple times
     *
     *	@param	newVals	the new value
     *	@return	this Builder
     */
    public IJournalBuilder addComment(String... newVals);

    /**
     *	Add these values as new comments
     *
     *	@param	newVals	the new value
     *	@return	this Builder
     */
    public IJournalBuilder addComment(List<String> newVals);

    /**
     *	remove one or more comments from this item
     *
     *	@param	oldVals	the comment to remove.  If the comment does not exist, this is a null-op
     *	@return	this Builder
     */
    public IJournalBuilder deleteComment(IComment... oldVals);

    /**
     *	remove a comment from this item
     *
     *	@param	oldVals	the comment to remove.  If the comment does not exist, this is a null-op
     *	@return	this Builder
     */
    public IJournalBuilder deleteComment(List<IComment> oldVals);

    /**
     *	modify a comment on this item
     *
     *	@param	base	the comment to modify.  If the comment does not exist, this is a null-op
     *	@param	comment	the replacement text
     *	@return	this Builder
     */
    public IJournalBuilder changeComment(IComment base, String comment);

    /**
     *	modify a comment on this item
     *
     *	@param	base	the comment to modify.  If the comment does not exist, this is a null-op
     *	@param	date	the replacement date
     *	@return	 this Builder
     */
    public IJournalBuilder changeComment(IComment base, LocalDate date);

    /**
     *	modify a comment on this item
     *
     *	@param	base	the comment to modify.  If the comment does not exist, this is a null-op
     *	@param	date	the replacement date
     *	@param	comment	the replacement text
     *	@return	this Builder
     */
    public IJournalBuilder changeComment(IComment base, LocalDate date, String comment);

    /**
     *	Check if the new or changed item needs to be saved
     *	i.e. has anything been changed?
     *
     *	@see #canSave()
     *
     *	@return	true if {@code save()} should be called
     *			false if nothing has been changed
     */
    public boolean needSave();

    /**
     *	Check if the new or changed item can be saved
     *	i.e. do all mandatory fields have a value?
     *
     *	@see #needSave()
     *
     *	@return	true if {@code save()} can be called safely
     *			false if there are unset mandatory values
     */
    public boolean canSave();

    /**
     *	Persist the new or changed instance to permanent storage
     *
     *	@return	A reference to the newly created or updated object
     *
     *	@throws	GNDBException	if the underlying persisted storage engine (e.g. database server) throws an exception
     *				The original error can be retrieved by <code>getCause()</code>
     */
    public IJournal save() throws GNDBException;

    /**
     *	Check if the item can be deleted
     *	i.e. are there any 'children' items?
     *
     *	@return	true if {@code delete()} can be called safely
     *			false if there are any 'children' items
     *
     *	@throws	GNDBException	if the underlying persisted storage engine (e.g. database server) throws an exception
     *				The original error can be retrieved by <code>getCause()</code>
     */
    public boolean canDelete() throws GNDBException;

    /**
     *	Delete the instance from permanent storage
     *
     *	@throws	GNDBException	if the underlying persisted storage engine (e.g. database server) throws an exception
     *				The original error can be retrieved by <code>getCause()</code>
     */
    public void delete() throws GNDBException;

}
