/***************************************************************************
 * Copyright (c)  2014  Zephyr Software LLC. All rights reserved.
 *
 * This software is furnished under a license and/or other restrictive
 * terms and may be used and copied only in accordance with such terms
 * and the inclusion of the above copyright notice. This software or
 * any other copies thereof may not be provided or otherwise made
 * available to any other person without the express written consent
 * of an authorized representative of Zephyr Software LCC. Title to,
 * ownership of, and all rights in the software is retained by
 * Zephyr Software LCC.
 *
 * Zephyr Software LLC. Proprietary Information
 *
 * Unless otherwise specified, the information contained in this
 * directory, following this legend, and/or referenced herein is
 * Zephyr Software LLC. (Zephyr) Proprietary Information. 
 *
 * CONTACT
 *
 * For technical assistance, contact Zephyr Software LCC. at:
 *      
 *
 * Zephyr Software, LLC
 * 2040 Tremont Rd
 * Charlottesville, VA 22911
 *
 * E-mail: jwd@zephyr-software.com
 **************************************************************************/

#ifndef dollop_man_h
#define dollop_man_h 

#include <dollop.h>
#include <set>
#include <map>
#include <list>


namespace Zipr_SDK {


typedef         std::set<Dollop_t*> DollopList_t;
typedef         std::map<IRDB_SDK::Instruction_t*,Dollop_t*>  InsnToDollopMap_t;
typedef         std::list<DollopPatch_t*>  DollopPatchList_t;
typedef         std::map<Dollop_t*, DollopPatchList_t > DollopToDollopPatchListMap_t;


class DollopManager_t {
	public:
		DollopManager_t() {};

		virtual size_t DetermineDollopEntrySize(DollopEntry_t *entry)=0;

		/*
		 * Add a dollop and all its fallthrough dollops
		 * to the dollop manager.
		 */
		virtual void AddDollops(Zipr_SDK::Dollop_t *dollop_head)=0;
		/*
		 * Create new dollops from a particular start instruction.
		 */
		virtual Zipr_SDK::Dollop_t *AddNewDollops(IRDB_SDK::Instruction_t *start)=0;

		/*
		 * Return the number of dollops under management.
		 */
		virtual size_t Size()=0;

		/*
		 * Return the dollop containing an instruction.
		 */
		virtual Zipr_SDK::Dollop_t *getContainingDollop(
			IRDB_SDK::Instruction_t *insn)=0;

		/*
		 * Add a dollop patch to the dollop manager.
		 */
		virtual void AddDollopPatch(Zipr_SDK::DollopPatch_t *new_patch) = 0;
		/*
		 * Return all the patches that point to a particular
		 * dollop.
		 */
		virtual std::list<Zipr_SDK::DollopPatch_t*> PatchesToDollop(
			Zipr_SDK::Dollop_t *target)=0;

		/*
		 * Update the dollops under management based on the
		 * targetted dollops in a particular dollop.
		 */
		virtual bool UpdateTargets(Zipr_SDK::Dollop_t *) = 0;
		/*
		 * Update all the dollops under management based on
		 * all the dollops of which the manager knows.
		 */
		virtual void UpdateAllTargets() = 0;

		/*
		 * Return beginning and ending iterators for all the
		 * dollops under management.
		 */
		virtual DollopList_t::iterator dollops_begin() = 0;
		virtual DollopList_t::iterator dollops_end() = 0;

		/*
		 * Print (for debugging) all the dollop patches
		 * under management.
		 */
		virtual void PrintDollopPatches(const std::ostream &) = 0;
		/*
		 * print (for debugging) information about the dollop
		 * manager.
		 */
		friend std::ostream &operator<<(std::ostream &out, const DollopManager_t &dollop_man);
		/*
		 * Print (useful output for end user) information about
		 * statistics of the dollop manager and the job it is
		 * doing.
		 */
		virtual void PrintStats(std::ostream &out) = 0;
		/*
		 * Generate a placement map file for all the dollops under management.
		 */
		virtual void PrintPlacementMap(const Zipr_SDK::MemorySpace_t &memory_space,
		                       const std::string &map_filename) = 0;
};
}
#endif