package com.enactor.pos;

import com.enactor.core.application.process.IApplicationProcessDataType;
import com.enactor.core.automation.AUT.AUTConfig;
import com.enactor.core.automation.AUT.AutomationException;
import com.enactor.core.automation.component.IComponentAccessor;

import java.rmi.RemoteException;
import java.util.List;

/**
 * Main interface for steps need to implemented for any steps provider
 */
public interface IPosStepsProvider {

    /**
     * Runs before each test
     *
     * @throws AutomationException
     */
    void beforeTest() throws AutomationException;

    /**
     * Runs after each test and check whether Enter User screen is shown
     *
     * @param clearTestPrinter
     * @throws Exception
     */
    void afterTestCheckEnterUserScreenShown(String testName, boolean clearTestPrinter, boolean testFailed) throws Exception;

    /**
     * Check window shown
     *
     * @param windowName
     * @throws AutomationException
     */
    void checkWindow(String windowName) throws AutomationException;

    /**
     * user waits component to display
     *
     * @param component
     * @param windowName
     * @throws AutomationException
     */
    void waitsForComponent(String component, String windowName) throws AutomationException;

    /**
     * Check component NOT display
     *
     * @param component
     * @param windowName
     * @throws AutomationException
     */
    void checkComponentNotDisplay(String component, String windowName) throws AutomationException;

    /**
     * Return the row content inside the requested component
     *
     * @param component
     * @param windowName
     * @return
     * @throws AutomationException
     */
    String getComponentInnerContent(String component, String windowName) throws AutomationException;

    /**
     * Click on given menu
     *
     * @param menuPath
     * @param windowName
     * @throws AutomationException
     */
    void pressMenu(String menuPath, String windowName) throws AutomationException;

    /**
     * Click on given button
     *
     * @param buttonLabel
     * @param windowName
     * @throws AutomationException
     */
    void pressButton(String buttonLabel, String windowName) throws AutomationException;

    /**
     * Press button by component
     *
     * @param componentName
     * @param windowName
     * @throws AutomationException
     */
    void pressButtonByComponent(String componentName, String windowName) throws AutomationException;

    /**
     * Check button with a given label NOT display on current page
     *
     * @param buttonLabel
     * @param windowName
     * @throws AutomationException
     */
    void checkButtonNotDisplay(String buttonLabel, String windowName) throws AutomationException;

    /**
     * Enter text on given field
     *
     * @param text
     * @param field
     * @param windowName
     * @throws AutomationException
     */
    void enterText(String text, String field, String windowName) throws AutomationException;

    /**
     * Enter text on given rich text field
     *
     * @param text
     * @param field
     * @param windowName
     * @throws AutomationException
     */
    void enterRichText(String text, String field, String windowName) throws AutomationException;

    /**
     * Check the component is not empty
     *
     * @throws AutomationException
     */
    void checkFieldIsNotEmpty(String componentName, String windowName) throws AutomationException;

    /**
     * Check text matches with text field's value.
     * <p>
     * eg: text field value : "Mr"
     * Matches text "Mr"
     * but not "mr" or "Mr."
     *
     * @param text
     * @param field
     * @param windowName
     * @throws AutomationException
     */
    void checkTextFieldValue(String text, String field, String windowName) throws AutomationException;

    /**
     * Check text field's value contains in the text.
     * <p>
     * eg: text field value : "Kit"
     * Contains with in the text "HD Complexion Starter Kit"
     *
     * @param text
     * @param field
     * @param windowName
     * @throws AutomationException
     */
    void checkTextFieldContainsValue(String text, String field, String windowName) throws AutomationException;

    /**
     * Check text matches with label field's value.
     * <p>
     * eg: text field value : "£0.00"
     * Matches text "£0.00"
     *
     * @param text
     * @param field
     * @param windowName
     * @throws AutomationException
     * @throws RemoteException
     */
    void checkLabelFieldValue(String text, String field, String windowName) throws AutomationException, RemoteException;

    /**
     * Verify text displayed in given panel component on given window
     *
     * @param text
     * @param panel
     * @param windowName
     * @throws AutomationException
     */
    void checkPanelTextDisplayed(String text, String panel, String windowName) throws AutomationException;

    /**
     * Select given item in the combobox
     *
     * @param item
     * @param field
     * @param windowName
     * @throws AutomationException
     * @throws InterruptedException
     */
    void selectComboboxItem(String item, String field, String windowName) throws AutomationException;

    /**
     * Check item appears in the list within given time frame.
     * eg: items with promotions takes few seconds to display in
     * the basket.
     *
     * @param item
     * @param list
     * @param windowName
     * @throws AutomationException
     * @throws InterruptedException
     */
    void checkListItemDisplay(String item, String list, String windowName) throws AutomationException;

    /**
     * Check item is not displayed in the list.
     * eg: items with promotions takes few seconds to display in
     * the basket.
     *
     * @param item
     * @param list
     * @param windowName
     * @throws AutomationException
     * @throws InterruptedException
     */
    void checkListItemNotDisplayed(String item, String list, String windowName) throws AutomationException;

    /**
     * Select given item in the list
     *
     * @param item
     * @param windowName
     * @throws AutomationException
     */
    void selectListItem(String item, String listName, String windowName) throws AutomationException;

    /**
     * Check receipt item flags.
     * ie: Item refund flag, Item void flag
     * Flag is always against an item. To check the flag
     * both item description and flag must be pass as an array
     * <p>
     * Flag - appears at the beginning of the line and space at the end
     * Item description - starts and ends with spaces
     * <p>
     * eg:  receipt text =>  "R   KAT VON D Eye Liner                -£18.00"
     * item array => ["R", "KAT VON D Eye Liner"] matches above receipt text
     * <p>
     * Eg: <b>R</b> for return
     *
     * @param entry
     * @throws AutomationException
     */
    int checkReceiptItemFlag(List<String> entry, int index) throws AutomationException;
    
    /**
     * Check receipt item flags on printer.
     * ie: Item refund flag, Item void flag
     * Flag is always against an item. To check the flag
     * both item description and flag must be pass as an array
     * <p>
     * Flag - appears at the beginning of the line and space at the end
     * Item description - starts and ends with spaces
     * <p>
     * eg:  receipt text =>  "R   KAT VON D Eye Liner                -£18.00"
     * item array => ["R", "KAT VON D Eye Liner"] matches above receipt text
     * <p>
     * Eg: <b>R</b> for return
     *
     * @param entry
     * @throws AutomationException
     */
    int checkReceiptItemFlagOnPrinter(List<String> entry, int index, String windowName) throws AutomationException;

    /**
     * check multiple line receipt entry.
     * address must be pass as List<String>
     * eg: [ "Enactor House","1 Bluecoats","Hertford","Hertfordshire","SG14 1PB" ]
     *
     * @param entry
     * @throws AutomationException
     */
    int checkMultipleLineReceiptEntry(List<String> entry, int index) throws AutomationException;
    
    /**
     * check multiple line receipt entryOn printer.
     * address must be pass as List<String>
     * eg: [ "Enactor House","1 Bluecoats","Hertford","Hertfordshire","SG14 1PB" ]
     *
     * @param entry
     * @throws AutomationException
     */
    int checkMultipleLineReceiptEntryOnPrinter(List<String> entry, int index, String windowName) throws AutomationException;

    /**
     * check multiple line receipt entry NOT display .
     * address must be pass as List<String>
     * eg: [ "Enactor House","1 Bluecoats","Hertford","Hertfordshire","SG14 1PB" ]
     *
     * @param entry
     * @throws AutomationException
     */
    int checkMultipleLineReceiptEntryNotDisplay(List<String> entry, int index) throws AutomationException;

    /**
     * check given text printed in the receipt.
     *
     * @param text
     * @throws AutomationException
     */
    int checkReceiptEntry(String text, int index) throws AutomationException;
    
    /**
     * check given text printed in the receipt on printer.
     *
     * @param text
     * @throws AutomationException
     */
    int checkReceiptEntryOnPrinter(String text, int index, String windowName) throws AutomationException;

    /**
     * check given text NOT printed in the receipt.
     *
     * @param text
     * @throws AutomationException
     */
    int checkReceiptEntryNotDisplay(String text, int index) throws AutomationException;

    /**
     * Block connections to the given uri
     *
     * @param uri
     * @throws AutomationException
     */
    void blockConnectionsToUri(String uri) throws AutomationException;

    /**
     * Unblock connections to the given uri
     *
     * @param uri
     * @throws AutomationException
     */
    void unblockConnectionsToUri(String uri) throws AutomationException;

    /**
     * Press a button with a given label on a test peripheral window
     *
     * @param buttonLabel
     * @param peripheralName
     * @throws AutomationException
     */
    void pressButtonOnTestPeripheral(String buttonLabel, String peripheralName) throws AutomationException;

    /**
     * Clear the printer.
     *
     * @throws AutomationException
     * @throws Exception
     */
    void clearPrinter() throws AutomationException;

    /**
     * Reads the file with the given fileName from the given path
     *
     * @param filePath
     * @throws AutomationException
     */
    void readTransactionXmlFromPath(String filePath, String filename) throws AutomationException;

    /**
     * Reads the transaction xml from the given path
     *
     * @param filePath
     * @throws AutomationException
     */
    void readTransactionXmlFromPath(String filePath) throws AutomationException;

    /**
     * Store current test's transaction IDs printed in the receipt
     *
     * @throws AutomationException
     */
    void storeTransactionID() throws AutomationException;

    /**
     * Returns the configs for Automation tests
     *
     * @return
     */
    AUTConfig getConfig();

    /**
     * Wait number of milliseconds provided
     * eg: waits(3000) // wait 3 seconds
     **/
    void waits(long milliseconds) throws AutomationException;

    /**
     * wait 1 second
     **/
    void waits() throws AutomationException;

    /**
     * restart the application if login screen is not shown.
     *
     * @throws Exception
     */
    void restartApplication() throws AutomationException;

    /**
     * Check text value need to be calculated
     * Text must be wrap inside #{text} if need to be calculated
     * <p>
     * eg:
     * text = #{today-2} will return day before yesterday in dd/mm/yy format
     * text = #{Sunday+1} will return this week's Monday in dd/mm/yy format
     *
     * @param text
     * @return
     * @throws AutomationException
     */
    String checkCalculationText(String text) throws AutomationException;

    /**
     * Checks data needs to be collected from property file
     *
     * @param value
     * @return string
     */
    String getTestData(String value) throws AutomationException;

    /**
     * get data from test data file
     *
     * @param name
     * @return string
     */
    String getTestDataValue(String name);

	/**
	 * Return the string in the format of <processId>-<promptUrl>
	 *
	 * @param windowName
	 * @return
	 * @throws AutomationException
	 */
	String getExtractedProcessIDandPromptIdFromWindowName(String windowName)
			throws AutomationException;

    /**
     * Add data to view.
     *
     * @param type Data type to add
     * @param data Data element to add
     *
     * @throws AutomationException
     */
    void addToViewData(IApplicationProcessDataType type, Object data) throws AutomationException;
    
    /**
     * Return the component accessible in given window id
     *
     * @param componentId Id of the accessing component
     * @param windowId Id of the window that the component is on
     * @return ComponentAccessor accessible component
     * 
     * @throws AutomationException
     */
    IComponentAccessor getComponentAccessor(String componentId, String windowId) throws AutomationException;
}
