/*
 * Copyright (C) 2018 "IoT.bzh"
 * Author Jonathan Aillet <jonathan.aillet@iot.bzh>
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#ifndef _HAL_UTILITIES_DATA_INCLUDE_
#define _HAL_UTILITIES_DATA_INCLUDE_

#include <stdio.h>

#include <wrap-json.h>

#include <afb/afb-binding.h>

#include <ctl-config.h>

#include "4a-hal-utilities-alsa-data.h"

#define HAL_UNKNOWN_DEVICE	-1

#define HAL_STREAM_UPDATES_EVENT_NAME		"stream-updates"

// Enum for hal status
enum HalStatus {
	HAL_STATUS_UNAVAILABLE=0,
	HAL_STATUS_AVAILABLE=1,
	HAL_STATUS_READY=2
};

// Enum for probed devices (dependencies) class
enum ProbedDeviceClasses {
	INVALID_PROBED_DEVICE=0,
	STATIC_PROBED_DEVICE=1,
	DYNAMIC_PROBED_DEVICE=2,
	MANDATORY_PROBED_DEVICE=3
};

// Structure to store data for audio devices validated by dependencies
struct InternalHalDeviceData {
	int cardNb;
	char *cardId;
	char *cardShortName;
	char *cardLongName;
	char *cardDriver;
	char *cardMixerName;
	char *cardComponents;
	int playbackDeviceNb;
	char *playbackDeviceId;
	char *playbackDeviceName;
	char *extendedCardNb;
};

// Structure to store one provided dependency
struct InternalHalProbedDevice {
	char *uid;
	enum ProbedDeviceClasses deviceClass;
	json_object *requestedDeviceJ;

	struct InternalHalDeviceData *deviceData;

	struct InternalHalProbedDevice *next;
};

// Structure to store stream data
struct InternalHalMixerData {
	char *verb;
	char *verbToCall;
	char *streamCardId;
	afb_event_t event;

	struct InternalHalMixerData *next;
};

// Structure to store specific internal hal data
struct InternalHalData {
	char *mixerApiName;
	char *prefix;
	json_object *halMixerJ;

	struct InternalHalProbedDevice *probedDevicesList;

	struct InternalHalMixerData *streamsData;
	afb_event_t streamUpdates;

	struct InternalHalAlsaMapT *alsaMapT;

	afb_api_t apiHandle;
	CtlConfigT *ctrlConfig;
};

// Structure to store specific hal (internal or external) data
struct HalData {
	char *apiName;
	enum HalStatus status;
	char *sndCardPath;
	int sndCardId;
	char *uid;
	char *info;
	unsigned int internal;

	char *author;
	char *version;
	char *date;
	// Can be beefed up if needed

	struct InternalHalData *internalHalData;		// Can be NULL if external api

	struct HalData *next;
};

// Structure to store hal manager data
struct HalMgrData {
	char *apiName;
	char *info;

	afb_api_t apiHandle;

	struct HalData *halDataList;
};

// Internal Hal - Probed devices structure handling functions
enum ProbedDeviceClasses HalUtlGetProbedDeviceClassFromString(char *probedDeviceString);
struct InternalHalProbedDevice *HalUtlAddProbedDeviceToProbedDeviceList(struct InternalHalProbedDevice **probedDevicesList);
int HalUtlRemoveSelectedProbedDeviceFromList(struct InternalHalProbedDevice **probedDevicesList,
					     struct InternalHalProbedDevice *probedDeviceToRemove);
int HalUtlRemoveAllProbedDevicesFromList(struct InternalHalProbedDevice **probedDevicesList);
int HalUtlGetNumberOfProbedDevicesInList(struct InternalHalProbedDevice **probedDevicesList);
struct InternalHalProbedDevice *HalUtlSearchProbedDeviceDataById(struct InternalHalProbedDevice **probedDevicesList,
								 char *uid);
struct InternalHalDeviceData *HalUtlAllocateAndFillProbedDeviceDataUsingInfoGetResponse(json_object *responseJ);

// Internal Hal - Streams data handling functions
struct InternalHalMixerData *HalUtlAddMixerDataToMixerDataList(struct InternalHalMixerData **mixerDataList);
int HalUtlRemoveSelectedMixerData(struct InternalHalMixerData **mixerDataList,
				  struct InternalHalMixerData *mixerDataToRemove);
int HalUtlRemoveAllMixerData(struct InternalHalMixerData **mixerDataList);
int HalUtlGetNumberOfMixerDataInList(struct InternalHalMixerData **mixerDataList);
struct InternalHalMixerData *HalUtlSearchMixerDataByProperties(struct InternalHalMixerData **mixerDataList,
							       char *verb, char *verbToCall,
							       char *streamCardId);
json_object *HalUtlGetJsonArrayForSpecificMixerData(afb_api_t apiHandle, struct InternalHalMixerData *mixerData);
json_object *HalUtlGetJsonArrayForAllMixersData(afb_api_t apiHandle, struct InternalHalMixerData **mixerDataList);

// Hal data handling functions
struct HalData *HalUtlAddHalToHalList(struct HalData **halDataList);
int HalUtlRemoveSelectedHalFromList(struct HalData **halDataList, struct HalData *halToRemove);
int HalUtlRemoveAllHalFromList(struct HalData **halDataList);
int HalUtlGetNumberOfHalInList(struct HalData **halDataList);
struct HalData *HalUtlSearchHalDataByApiName(struct HalData **halDataList, char *apiName);
struct HalData *HalUtlSearchReadyHalDataByCardId(struct HalData **halDataList, int cardId);

// Hal Manager data handling functions
int HalUtlInitializeHalMgrData(afb_api_t apiHandle, struct HalMgrData *halMgrData, char *apiName, char *info);
void HalUtlRemoveHalMgrData(struct HalMgrData *halMgrData);

#endif /* _HAL_UTILITIES_DATA_INCLUDE_ */