/* IdGenerator.java

	Purpose:
		
	Description:
		
	History:
		Thu Jun 21 12:00:55     2007, Created by tomyeh

Copyright (C) 2007 Potix Corporation. All Rights Reserved.

{{IS_RIGHT
	This program is distributed under LGPL Version 2.1 in the hope that
	it will be useful, but WITHOUT ANY WARRANTY.
}}IS_RIGHT
*/
package org.zkoss.zk.ui.sys;

import org.zkoss.zk.ui.Component;
import org.zkoss.zk.ui.Desktop;
import org.zkoss.zk.ui.Page;
import org.zkoss.zk.ui.metainfo.ComponentInfo;

/**
 * Used to generate UUID of components and pages and ID of desktops.
 *
 * <p>To create an ID generator that generates the same set of IDs from
 * one test run to anther, you need only to implement {@link #nextDesktopId}
 * to return a deterministic value. All other methods just return null
 * to use the default.
 *
 * @author tomyeh
 * @see Component#getUuid
 * @see Page#getUuid
 * @see Desktop#getId
 * @since 2.4.1
 */
public interface IdGenerator {
	/** Returns the next component UUID for the specified component,
	 * or null to generate the default UUID.
	 *
	 * <p>Default (if null is returned): UUID is generated by prefixing
	 * a portion of the desktop's ID with a number starting from 0.
	 *
	 * <p>Notice that UUID cannot be empty and can only have alphanumeric characters or underscore
	 * (i.e., a-z, A-Z, 0-9, and _).
	 *
	 * <p>This method is called when {@link Component#getUuid}
	 * is called at the first time. It is usually when
	 * the component is attached to a page, unless the application
	 * invokes {@link Component#getUuid} earlier.
	 *
	 * @param desktop the current desktop (never null)
	 * @param comp the component (never null)
	 * @param compInfo the information about the properties specified in the ZUML
	 * document, null if the component is instantiated manually. 
	 * @return the next component UUID, or null to generate the
	 * @since 6.0.1
	 */
	default String nextComponentUuid(Desktop desktop, Component comp, ComponentInfo compInfo) {
		return null;
	}

	/** Returns the next anonymous component UUID for the specified component,
	 * or null to generate the default UUID.
	 * <p>Unlike {@link #nextComponentUuid(Desktop, Component, ComponentInfo)},
	 * this uuid is not belonged to any desktop scope, but application or clustering environment scope.
	 * A typical usage is for Stateless component application in Cloud mode and the
	 * generated uuid must be an unique id among the clustering servers environment.
	 *
	 * <p>Default (if null is returned): UUID is generated by prefixing
	 * a portion of the {@code "z__i"} ID with a number starting from 0. (The implementation
	 * is the same as before ZK 10.)
	 *
	 * @param comp the component (never null)
	 * @param compInfo the information about the properties specified in the ZUML
	 * document, null if the component is instantiated manually.
	 * @return the next component UUID, or null to generate the
	 * @since 10.0.0
	 */
	default String nextAnonymousComponentUuid(Component comp, ComponentInfo compInfo) {
		return null;
	}

	/** Returns the next page UUID for the specified page,
	 * or null to generate the default UUID.
	 *
	 * <p>Default (if null is returned): UUID is generated by prefixing
	 * a portion of the desktop's ID with a number starting from 0.
	 *
	 * <p>Notice that UUID cannot be empty and can only have alphanumeric characters or underscore
	 * (i.e., a-z, A-Z, 0-9, and _).
	 * In additions, UUID for pages cannot be the same as UUID for components.
	 *
	 * <p>Also notice that the execution can be retrieved by use of
	 * {@link org.zkoss.zk.ui.Executions#getCurrent}.
	 *
	 * @return the next page UUID, or null to generate the
	 * default UUID.
	 */
	default String nextPageUuid(Page page) {
		return null;
	}

	/** Returns the next desktop ID for the specified desktop,
	 * or null to generate the default ID.
	 *
	 * <p>Default (if null is returned): ID is generated randomly.
	 * In other words, the desktop's ID, by default, is not deterministic.
	 * To have a deterministic value, you have to implement this method.
	 *
	 * <p>Notice that UUID cannot be empty and can only have alphanumeric characters or underscore
	 * (i.e., a-z, A-Z, 0-9, and _).
	 *
	 * <p>Also notice that we can retrieve the execution by use of
	 * {@link Desktop#getExecution}, or {@link org.zkoss.zk.ui.Executions#getCurrent}.
	 *
	 * @return the next desktop ID, or null to generate the default ID.
	 */
	default String nextDesktopId(Desktop desktop) {
		return null;
	}
}
