use crate*;
/// General function that can create any entry type.
///
/// This is used under the hood by [ `create_entry` ], [ `create_cap_grant` ] and [ `create_cap_claim` ].
///
/// The host builds a [ `Create` ] header for the passed entry value and commits a new element to the
/// chain.
///
/// Usually you don't need to use this function directly; it is the most general way to create an
/// entry and standardises the internals of higher level create functions.
/// Update any entry type.
///
/// This is used under the hood by [ `update_entry` ], [ `update_cap_grant` ] and `update_cap_claim`.
/// @todo implement update_cap_claim
///
/// The host builds an [ `Update` ] header for the passed entry value and commits a new update to the
/// chain.
///
/// Usually you don't need to use this function directly; it is the most general way to update an
/// entry and standardises the internals of higher level create functions.
/// General function that can delete any entry type.
///
/// This is used under the hood by [ `delete_entry` ], [ `delete_cap_grant` ] and `delete_cap_claim`.
/// @todo implement delete_cap_claim
///
/// The host builds a [ `Delete` ] header for the passed entry and commits a new element to the chain.
///
/// Usually you don't need to use this function directly; it is the most general way to update an
/// entry and standardises the internals of higher level create functions.
/// Create an app entry.
///
/// Apps define app entries by registering entry def ids with the `entry_defs` callback and serialize the
/// entry content when committing to the source chain.
///
/// This function accepts any input that implements [ `TryInto<EntryWithDefId>` ].
/// The default impls from the `#[hdk_entry( .. )]` and [ `entry_def!` ] macros include this.
///
/// With generic type handling it may make sense to directly construct [ `EntryWithDefId` ] and [ `create` ].
///
/// e.g.
/// ```ignore
/// #[hdk_entry(id = "foo")]
/// pub struct Foo(u32);
/// create_entry(Foo(50))?;
/// ```
///
/// See [ `get` ] and [ `get_details` ] for more information on CRUD.
/// Alias to delete
///
/// Takes the [ `HeaderHash` ] of the element to delete.
///
/// ```ignore
/// delete_entry(entry_hash(foo_entry)?)?;
/// ```
/// Hash anything that that implements [ `TryInto<Entry>` ].
///
/// Hashes are typed in holochain, e.g. [ `HeaderHash` ] and [ `EntryHash` ] are different and yield different
/// bytes for a given value. This ensures correctness and allows type based dispatch in various
/// areas of the codebase.
///
/// Usually you want to hash a value that you want to reference on the DHT with [ `get` ] etc. because
/// it represents some domain-specific data sourced externally or generated within the wasm.
/// [ `HeaderHash` ] hashes are _always_ generated by the process of committing something to a local
/// chain. Every host function that commits an entry returns the new [ `HeaderHash` ]. The [ `HeaderHash` ] can
/// also be used with [ `get` ] etc. to retreive a _specific_ element from the DHT rather than the
/// oldest live element.
/// However there is no way to _generate_ a header hash directly from a header from inside wasm.
/// [ `Element` ] values (entry+header pairs returned by [ `get` ] etc.) contain prehashed header structs
/// called [ `HeaderHashed` ], which is composed of a [ `HeaderHash` ] alongside the "raw" [ `Header` ] value. Generally the pre-hashing is
/// more efficient than hashing headers ad-hoc as hashing always needs to be done at the database
/// layer, so we want to re-use that as much as possible.
/// The header hash can be extracted from the Element as `element.header_hashed().as_hash()`.
/// @todo is there any use-case that can't be satisfied by the `header_hashed` approach?
///
/// Anything that is annotated with #[hdk_entry( .. )] or entry_def!( .. ) implements this so is
/// compatible automatically.
///
/// [ `hash_entry` ] is "dumb" in that it doesn't check that the entry is defined, committed, on the DHT or
/// any other validation, it simply generates the hash for the serialized representation of
/// something in the same way that the DHT would.
///
/// It is strongly recommended that you use the [ `hash_entry` ] function to calculate hashes to avoid
/// inconsistencies between hashes in the wasm guest and the host.
/// For example, a lot of the crypto crates in rust compile to wasm so in theory could generate the
/// hash in the guest, but there is the potential that the serialization logic could be slightly
/// different, etc.
///
/// ```ignore
/// #[hdk_entry(id="foo")]
/// struct Foo;
///
/// let foo_hash = hash_entry(Foo)?;
/// ```
/// Thin wrapper around update for app entries.
/// The hash is the [ `HeaderHash` ] of the deleted element, the input is a [ `TryInto<EntryWithDefId>` ].
///
/// Updates can reference Elements which contain Entry data -- namely, Creates and other Updates -- but
/// not Deletes or system Elements
///
/// As updates can reference elements on other agent's source chains across unpredictable network
/// topologies, they are treated as a tree structure.
///
/// Many updates can point to a single create/update and continue to accumulate as long as agents
/// author them against that element. It is up to happ developers to decide how to ensure the tree
/// branches are walked appropriately and that updates point to the correct element, whatever that
/// means for the happ.
///
/// ```ignore
/// #[hdk_entry(id = "foo")]
/// struct Foo(u32);
///
/// let foo_zero_header_hash: HeaderHash = commit_entry!(Foo(0))?;
/// let foo_ten_update_header_hash: HeaderHash = update_entry(foo_zero_header_hash, Foo(10))?;
/// ```
///
/// @todo in the future this will be true because we will have the concept of 'redirects':
/// Works as an app entry delete+create.
///
/// See [ `create_entry` ]
/// See [ `update` ]
/// See [ `delete_entry` ]
/// Gets an element for a given entry or header hash.
///
/// The behaviour of get changes subtly per the _type of the passed hash_.
/// A header hash returns the element for that header, i.e. header+entry or header+None.
/// An entry hash returns the "oldest live" element, i.e. header+entry.
///
/// An element is no longer live once it is referenced by a valid delete element.
/// An update to an element does not change its liveness.
/// See [ `get_details` ] for more information about how CRUD elements reference each other.
///
/// Note: [ `get` ] __always triggers and blocks on a network call__.
/// @todo implement a 'get optimistic' that returns based on the current opinion of the world
/// and performs network calls in the background so they are available 'next time'.
///
/// Note: Deletes are considered in the liveness but Updates are not currently followed
/// automatically due to the need for the happ to disambiguate update logic.
/// @todo implement 'redirect' logic so that updates are followed by [ `get` ].
///
/// Note: Updates typically point to a different entry hash than what they are updating but not
/// always, e.g. consider changing `foo` to `bar` back to `foo`. The entry hashes in a crud
/// tree can be circular but the header hashes are never circular.
/// In this case, deleting the create for foo would make the second update pointing to foo
/// the "oldest live" element.
///
/// Note: "oldest live" only relates to disambiguating many creates and updates from many authors
/// pointing to a single entry, it is not the "current value" of an entry in a CRUD sense.
/// e.g. If "foo" is created then updated to "bar", a [ `get` ] on the hash of "foo" will return
/// "foo" as part of an element with the "oldest live" header.
/// To discover "bar" the agent needs to call `get_details` and decide how it wants to
/// collapse many potential creates, updates and deletes down into a single or filtered
/// set of updates, to "walk the tree".
/// e.g. Updates could include a proof of work and a tree would collapse to a simple
/// blockchain if the agent follows the "heaviest chain".
/// e.g. Updates could represent turns in a 2-player game and the update with the newest
/// timestamp countersigned by both players represents an opt-in chain of updates with
/// support for casual "undo" with player's consent.
/// e.g. Domain/user names could be claimed on a "first come, first serve" basis with only
/// creates and deletes allowed by validation rules, the "oldest live" element _does_
/// represent the element pointing at the first agent to claim a name, but it could also
/// be checked manually by the app with `get_details`.
///
/// Note: "oldest live" is only as good as the information available to the authorities the agent
/// contacts on their current network partition, there could always be an older live entry
/// on another partition, and of course the oldest live entry could be deleted and no longer
/// be live.
/// Get an element from the hash AND the details for the entry or header hash passed in.
/// Returns [ `None` ] if the entry/header does not exist.
/// The details returned are a contextual mix of elements and header hashes, see below.
///
/// Note: The return details will be inferred by the hash type passed in, be careful to pass in the
/// correct hash type for the details you want.
///
/// Note: If a header hash is passed in the element returned is the specified element.
/// If an entry hash is passed in all the headers (so implicitly all the elements) are
/// returned for the entry that matches that hash.
/// See [ `get` ] for more information about what "oldest live" means.
///
/// The details returned include relevant creates, updates and deletes for the hash passed in.
///
/// Creates are initial header/entry combinations (elements) produced by commit_entry! and cannot
/// reference other headers.
/// Updates and deletes both reference a specific header+entry combination.
/// Updates must reference another create or update header+entry.
/// Deletes must reference a create or update header+entry (nothing can reference a delete).
///
/// Full elements are returned for direct references to the passed hash.
/// Header hashes are returned for references to references to the passed hash.
///
/// [ `Details` ] for a header hash return:
/// - the element for this header hash if it exists
/// - all update and delete _elements_ that reference that specified header
///
/// [ `Details` ] for an entry hash return:
/// - all creates, updates and delete _elements_ that reference that entry hash
/// - all update and delete _elements_ that reference the elements that reference the entry hash
///
/// Note: Entries are just values, so can be referenced by many CRUD headers by many authors.
/// e.g. the number 1 or string "foo" can be referenced by anyone publishing CRUD headers at
/// any time they need to represent 1 or "foo" for a create, update or delete.
/// If you need to disambiguate entry values, provide uniqueness in the entry value such as
/// a unique hash (e.g. current chain head), timestamp (careful about collisions!), or random
/// bytes/uuid (see random_bytes() and the uuid rust crate that supports uuids from bytes).
///
/// Note: There are multiple header types that exist and operate entirely outside of CRUD elements
/// so they cannot reference or be referenced by CRUD, so are immutable or have their own
/// mutation logic (e.g. link create/delete) and will not be included in [ `get_details` ] results
/// e.g. the DNA itself, links, migrations, etc.
/// However the element will still be returned by [ `get_details` ] if a header hash is passed,
/// these header-only elements will have [ `None` ] as the entry value.
/// Trait for binding static [ `EntryDef` ] property access for a type.
/// See [ `register_entry` ]
/// Implements conversion traits to allow a struct to be handled as an app entry.
/// If you have some need to implement custom serialization logic or metadata injection
/// you can do so by implementing these traits manually instead.
///
/// This requires that TryFrom and TryInto [ `derive@SerializedBytes` ] is implemented for the entry type,
/// which implies that [ `serde::Serialize` ] and [ `serde::Deserialize` ] is also implemented.
/// These can all be derived and there is an attribute macro that both does the default defines.
/// Implements a whole lot of sane defaults for a struct or enum that should behave as an entry,
/// *without* implementing the app entry conversion interface.
///
/// This allows crates to easily define a struct as an entry separately to binding that struct
/// as an entry type in a dependent crate.
///
/// For most normal applications, you should use the [ `entry_def!` ] macro instead.
/// Implements a whole lot of sane defaults for a struct or enum that should behave as an entry.
/// All the entry def fields are available as dedicated methods on the type and matching From impls
/// are provided for each. This allows for both Foo::entry_def() and EntryDef::from(Foo::new())
/// style logic which are both useful in different scenarios.
///
/// For example, the Foo::entry_def() style works best in the entry_defs callback as it doesn't
/// require an instantiated Foo in order to get the definition.
/// On the other hand, EntryDef::from(Foo::new()) works better when e.g. using create_entry() as
/// an instance of Foo already exists and we need the entry def id back for creates and updates.
///
/// If you don't want to use the macro you can simply implement similar fns youself.
///
/// This is not a trait at the moment, it could be in the future but for now these functions and
/// impls are just a loose set of conventions.
///
/// It's actually entirely possible to interact with core directly without any of these.
/// e.g. [ `create_entry` ] is just building a tuple of [ `EntryDefId` ] and [ `Entry::App` ] under the hood.
///
/// This requires that TryFrom and TryInto [ `derive@SerializedBytes` ] is implemented for the entry type,
/// which implies that [ `serde::Serialize` ] and [ `serde::Deserialize` ] is also implemented.
/// These can all be derived and there is an attribute macro that both does the default defines.
///
/// e.g. the following are equivalent
///
/// ```ignore
/// #[hdk_entry(id = "foo", visibility = "private", required_validations = 6, )]
/// pub struct Foo;
/// ```
///
/// ```ignore
/// #[derive(SerializedBytes, serde::Serialize, serde::Deserialize)]
/// pub struct Foo;
/// entry_def!(Foo EntryDef {
/// id: "foo".into(),
/// visibility: EntryVisibility::Private,
/// ..Default::default()
/// });
/// ```
/// Shorthand to implement the entry defs callback similar to the vec![ .. ] macro but for entries.
///
/// e.g. the following are the same
///
/// ```ignore
/// entry_defs![ Foo::entry_def() ];
/// ```
///
/// ```ignore
/// #[hdk_extern]
/// fn entry_defs(_: ()) -> ExternResult<EntryDefsCallbackResult> {
/// Ok(vec![ Foo::entry_def() ].into())
/// }
/// ```
};
}
/// Attempts to lookup the [ `EntryDefIndex` ] given an [ `EntryDefId` ].
///
/// The [ `EntryDefId` ] is a [ `String` ] newtype and the [ `EntryDefIndex` ] is a u8 newtype.
/// The [ `EntryDefIndex` ] is used to reference the entry type in headers on the DHT and as the index of the type exported to tooling.
/// The [ `EntryDefId` ] is the 'human friendly' string that the [ `entry_defs!` ] callback maps to the index.
///
/// The host actually has no idea how to do this mapping, it is provided by the wasm!
///
/// Therefore this is a macro that calls the [ `entry_defs!` ] callback as defined within a zome directly from the zome.
/// It is a macro so that we can call a function with a known name `crate::entry_defs` from the HDK before the function is defined.
///
/// Obviously this assumes and requires that a compliant [ `entry_defs!` ] callback _is_ defined at the root of the crate.