/**
 * Copyright (c) 2014 Etherios, a Division of Digi International Inc.
 * All rights not expressly granted are reserved.
 *
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this file,
 * You can obtain one at http://mozilla.org/MPL/2.0/.
 *
 * Etherios 11001 Bren Road East, Minnetonka, MN 55343
 * =======================================================================
 */
package com.etherios.connector.emulator.firmware;

import com.etherios.connector.core.facilities.firmware.FirmwareConstants;

import com.etherios.connector.core.facilities.firmware.FirmwareTarget;

/**
 * This interface lists all the required methods that must be implemented in 
 * order to extend the Device firmware update functionality using Cloud 
 * Connector.
 * 
 * <p>In order to extend Cloud Connector firmware functionality, a class 
 * implementing this interface must be passed as parameter in the Cloud 
 * Connector constructor: 
 * {@link com.etherios.connector.emulator.CloudConnector#CloudConnector(IGeneralFirmwareImplementation)}</p>
 * 
 * <p>The parameter {@value com.etherios.connector.emulator.firmware.GeneralFirmwareManager#PARAM_FIRMWARE_FILE_NOTIFY} 
 * must be defined in the {@code connector_config.txt} file:</p>
 * 
 * <ul>
 * <li>{@value com.etherios.connector.emulator.firmware.GeneralFirmwareManager#FIRMWARE_FILE_NOTIFY_FILE}</li>
 * <li>{@value com.etherios.connector.emulator.firmware.GeneralFirmwareManager#FIRMWARE_FILE_NOTIFY_CHUNK}</li>
 * </ul>
 * 
 * <p>To define the available targets follow the instructions described in 
 * {@link com.etherios.connector.emulator.firmware.GeneralFirmwareManager}.</p>
 * 
 * @see GeneralFirmwareManager#PARAM_FIRMWARE_FILE_NOTIFY
 * @see GeneralFirmwareManager#FIRMWARE_FILE_NOTIFY_FILE
 * @see GeneralFirmwareManager#FIRMWARE_FILE_NOTIFY_CHUNK
 * @see FirmwareTarget
 * @see com.etherios.connector.emulator.CloudConnector
 */
public interface IGeneralFirmwareImplementation {

	/**
	 * This method is called whenever a firmware update process is about to 
	 * start.
	 * 
	 * @param target The firmware target for which firmware update is about to 
	 *               start.
	 * @param size The size (in bytes) of the firmware file that will be sent 
	 *             from Device Cloud.
	 * @param fileName The name of the firmware file that will be sent.
	 * @return Download response code.
	 * 
	 * @see FirmwareConstants#DOWNLOAD_RESPONSE_TYPE_OK
	 * @see FirmwareConstants#DOWNLOAD_RESPONSE_TYPE_DOWNLOAD_DENIED
	 * @see FirmwareConstants#DOWNLOAD_RESPONSE_TYPE_FILE_TOO_LARGE
	 * @see FirmwareConstants#DOWNLOAD_RESPONSE_TYPE_INVALID_VERSION
	 * @see FirmwareConstants#DOWNLOAD_RESPONSE_TYPE_NOT_AUTHENTICATED
	 * @see FirmwareConstants#DOWNLOAD_RESPONSE_TYPE_NOT_ALLOWED
	 * @see FirmwareConstants#DOWNLOAD_RESPONSE_TYPE_REJECT
	 * @see FirmwareConstants#DOWNLOAD_RESPONSE_TYPE_ERROR
	 */
	public int firmwareUpdateStart(FirmwareTarget target, int size, String fileName);
	
	/**
	 * This method is called whenever a full file is downloaded using the 
	 * firmware update service. If configuration is set not to be notified when 
	 * the full file is downloaded, this method will never be called.
	 * 
	 * <p>The parameter 
	 * {@value com.etherios.connector.emulator.firmware.GeneralFirmwareManager#PARAM_FIRMWARE_FILE_NOTIFY} must 
	 * be configured to 
	 * {@value com.etherios.connector.emulator.firmware.GeneralFirmwareManager#FIRMWARE_FILE_NOTIFY_FILE}.</p>
	 * 
	 * @param filePath The downloaded firmware file path.
	 * @return {@code true} if the file is successfully handled, {@code false} 
	 *         if an error occurs.
	 * 
	 * @see GeneralFirmwareManager#PARAM_FIRMWARE_FILE_NOTIFY
	 * @see GeneralFirmwareManager#FIRMWARE_FILE_NOTIFY_FILE
	 * @see GeneralFirmwareManager#FIRMWARE_FILE_NOTIFY_CHUNK
	 */
	public boolean fileReceived(String filePath);
	
	/**
	 * This method is called whenever a new file chunk is received during
	 * a firmware update. If the configuration is set not to be notified when 
	 * a new file chunk is received, this method will never be called.
	 * 
	 * <p>The parameter 
	 * {@value com.etherios.connector.emulator.firmware.GeneralFirmwareManager#PARAM_FIRMWARE_FILE_NOTIFY} must be 
	 * configured to {@value com.etherios.connector.emulator.firmware.GeneralFirmwareManager#FIRMWARE_FILE_NOTIFY_CHUNK}
	 * .</p>
	 * 
	 * @param data Byte array with the data chunk received.
	 * @return {@code true} if data chunk is successfully handled, {@code false} 
	 *         if an error occurs.
	 * 
	 * @see GeneralFirmwareManager#PARAM_FIRMWARE_FILE_NOTIFY
	 * @see GeneralFirmwareManager#FIRMWARE_FILE_NOTIFY_CHUNK
	 * @see GeneralFirmwareManager#FIRMWARE_FILE_NOTIFY_FILE
	 */
	public boolean dataChunkReceived(byte[] data);
	
	/**
	 * This method is called when the download of the firmware is complete, and 
	 * no more file chunks are going to be sent. If the configuration is set not 
	 * to be notified when a new file chunk is received, this method will never 
	 * be called.
	 * 
	 * <p>The parameter 
	 * {@value com.etherios.connector.emulator.firmware.GeneralFirmwareManager#PARAM_FIRMWARE_FILE_NOTIFY} must be 
	 * configured to {@value com.etherios.connector.emulator.firmware.GeneralFirmwareManager#FIRMWARE_FILE_NOTIFY_CHUNK}
	 * .</p>
	 * 
	 * <p>Handles a download complete event from the server indicating that the 
	 * new firmware file has been completely transferred.</p>
	 * 
	 * @param checksum CRC-32 checksum value computed from offset 0 to 
	 *                 {@code size} (calculated by the server), {@code 0} if no 
	 *                 checksum is required.
	 * @return Download complete status:
	 * <ul>
	 * <li>{@link FirmwareConstants#DOWNLOAD_COMPLETE_STATUS_OK}</li>
	 * <li>{@link FirmwareConstants#DOWNLOAD_COMPLETE_STATUS_ERROR}</li>
	 * <li>{@link FirmwareConstants#DOWNLOAD_COMPLETE_STATUS_CHECKSUM_ERROR}</li>
	 * </ul>
	 * 
	 * @see FirmwareConstants#DOWNLOAD_COMPLETE_STATUS_OK
	 * @see FirmwareConstants#DOWNLOAD_COMPLETE_STATUS_ERROR
	 * @see FirmwareConstants#DOWNLOAD_COMPLETE_STATUS_CHECKSUM_ERROR
	 * @see GeneralFirmwareManager#PARAM_FIRMWARE_FILE_NOTIFY
	 * @see GeneralFirmwareManager#FIRMWARE_FILE_NOTIFY_CHUNK
	 * @see GeneralFirmwareManager#FIRMWARE_FILE_NOTIFY_FILE
	 */
	public int dataChunkDownloadComplete(byte[] checksum);
	
	/**
	 * This method is called whenever an error occurs in the current firmware 
	 * update process.
	 */
	public void firmwareUpdateError();
	
	/**
	 * Notifies that the firmware update process was aborted by the server for 
	 * the given reason.
	 * 
	 * @param reason Reason of the firmware update abort:
	 * <ul>
	 * <li>{@link FirmwareConstants#ABORT_SERVER_CLIENT}</li>
	 * <li>{@link FirmwareConstants#ABORT_DOWNLOAD_ERROR}</li>
	 * </ul>
	 * 
	 * @see FirmwareConstants#ABORT_SERVER_CLIENT
	 * @see FirmwareConstants#ABORT_DOWNLOAD_ERROR
	 */
	public void firmwareDownloadAbort(int reason);
}
