"use strict";

const matchValue = require("match-value");

const operations = require("../operations");
const internalOperations = require("../internal-operations");
const NoChange = require("./util/no-change");
const typeOf = require("../type-of");

let valueListTypes = new Set([ "anyOfValues", "allOfValues" ]);

module.exports = {
	name: "values-to-conditions",
	category: [ "normalization" ],
	visitors: {
		condition: (rootNode) => {
			let isListType = valueListTypes.has(typeOf(rootNode.expression));
			let listContainsArray = isListType && Array.isArray(rootNode.expression.items); // FIXME: Make this `unpackable` metadata on the AST node?

			if (!isListType || !listContainsArray) {
				return NoChange;
			} else {
				function convertListNode(node) {
					let listOperation = matchValue.literal(typeOf(node), {
						anyOfValues: operations.anyOf,
						allOfValues: operations.allOf,
					});

					let conditions = node.items.map((item) => {
						if (valueListTypes.has(typeOf(item))) {
							return convertListNode(item);
						} else {
							return internalOperations._condition({
								type: rootNode.conditionType,
								expression: item
							});
						}
					});

					return listOperation(conditions);
				}

				return convertListNode(rootNode.expression);
			}
		}
	}
};
