/*
 * Copyright (c) 2018 Intel Corporation.
 * Copyright (c) 2021 Nordic Semiconductor ASA
 *
 * SPDX-License-Identifier: Apache-2.0
 */

#include <zephyr/pm/state.h>
#include <zephyr/toolchain.h>

BUILD_ASSERT(DT_NODE_EXISTS(DT_PATH(cpus)),
	     "cpus node not defined in Devicetree");

#define DEFINE_CPU_STATES(n) \
	static const struct pm_state_info pmstates_##n[] \
		= PM_STATE_INFO_LIST_FROM_DT_CPU(n);
#define CPU_STATE_REF(n) pmstates_##n

DT_FOREACH_CHILD(DT_PATH(cpus), DEFINE_CPU_STATES);

/** CPU power states information for each CPU */
static const struct pm_state_info *cpus_states[] = {
	DT_FOREACH_CHILD_STATUS_OKAY_SEP(DT_PATH(cpus), CPU_STATE_REF, (,))
};

/** Number of states for each CPU */
static const uint8_t states_per_cpu[] = {
	DT_FOREACH_CHILD_STATUS_OKAY_SEP(DT_PATH(cpus), DT_NUM_CPU_POWER_STATES, (,))
};

#define DEFINE_DISABLED_PM_STATE(node) \
	IF_ENABLED(DT_NODE_HAS_STATUS(node, disabled), (PM_STATE_INFO_DT_INIT(node),))

/** Check if power states exists in the Devicetree. */
#define POWER_STATES_EXISTS()						       \
	UTIL_OR(DT_NODE_EXISTS(DT_PATH(cpus, power_states)),		       \
		DT_NODE_EXISTS(DT_PATH(power_states)))

/** Get node with power states. Macro assumes that power states exists. */
#define POWER_STATES_NODE()						       \
	COND_CODE_1(DT_NODE_EXISTS(DT_PATH(cpus, power_states)),	       \
		    (DT_PATH(cpus, power_states)), (DT_PATH(power_states)))

/* Array with all states which are disabled but can be forced. */
static const struct pm_state_info disabled_states[] = {
	IF_ENABLED(POWER_STATES_EXISTS(),
		   (DT_FOREACH_CHILD(POWER_STATES_NODE(), DEFINE_DISABLED_PM_STATE)))
};

uint8_t pm_state_cpu_get_all(uint8_t cpu, const struct pm_state_info **states)
{
	if (cpu >= ARRAY_SIZE(cpus_states)) {
		return 0;
	}

	*states = cpus_states[cpu];

	return states_per_cpu[cpu];
}

const struct pm_state_info *pm_state_get(uint8_t cpu, enum pm_state state, uint8_t substate_id)
{
	__ASSERT_NO_MSG(cpu < ARRAY_SIZE(cpus_states));
	const struct pm_state_info *states = cpus_states[cpu];
	uint8_t cnt = states_per_cpu[cpu];

	for (uint8_t i = 0; i < cnt; i++) {
		if ((states[i].state == state) && (states[i].substate_id == substate_id)) {
			return &states[i];
		}
	}

	for (uint8_t i = 0; i < ARRAY_SIZE(disabled_states); i++) {
		if ((disabled_states[i].state == state) &&
		    (disabled_states[i].substate_id == substate_id)) {
			return &disabled_states[i];
		}
	}

	return NULL;
}

const char *pm_state_to_str(enum pm_state state)
{
	switch (state) {
	case PM_STATE_ACTIVE:
		return "active";
	case PM_STATE_RUNTIME_IDLE:
		return "runtime-idle";
	case PM_STATE_SUSPEND_TO_IDLE:
		return "suspend-to-idle";
	case PM_STATE_STANDBY:
		return "standby";
	case PM_STATE_SUSPEND_TO_RAM:
		return "suspend-to-ram";
	case PM_STATE_SUSPEND_TO_DISK:
		return "suspend-to-disk";
	case PM_STATE_SOFT_OFF:
		return "soft-off";
	default:
		return "UNKNOWN";
	}
}

int pm_state_from_str(const char *name, enum pm_state *out)
{
	if (strcmp(name, "active") == 0) {
		*out = PM_STATE_ACTIVE;
	} else if (strcmp(name, "runtime-idle") == 0) {
		*out = PM_STATE_RUNTIME_IDLE;
	} else if (strcmp(name, "suspend-to-idle") == 0) {
		*out = PM_STATE_SUSPEND_TO_IDLE;
	} else if (strcmp(name, "standby") == 0) {
		*out = PM_STATE_STANDBY;
	} else if (strcmp(name, "suspend-to-ram") == 0) {
		*out = PM_STATE_SUSPEND_TO_RAM;
	} else if (strcmp(name, "suspend-to-disk") == 0) {
		*out = PM_STATE_SUSPEND_TO_DISK;
	} else if (strcmp(name, "soft-off") == 0) {
		*out = PM_STATE_SOFT_OFF;
	} else {
		return -EINVAL;
	}

	return 0;
}

bool pm_state_in_constraints(const struct pm_state_constraints *constraints,
			     const struct pm_state_constraint match)
{
	struct pm_state_constraint *constraints_list = constraints->list;
	size_t num_constraints = constraints->count;
	bool match_found = false;

	for (int i = 0; i < num_constraints; i++) {
		enum pm_state state = constraints_list[i].state;
		uint8_t substate = constraints_list[i].substate_id;

		match_found |= ((state == match.state) && (substate == match.substate_id));
	}

	return match_found;
}
