"use strict";

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

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

module.exports = {
	name: "conditions-to-expressions",
	category: [ "normalization" ],
	visitors: {
		expression: (rootNode) => {
			if (rootNode.condition.type === "condition") {
				return NoChange;
			} else {
				// anyOfConditions, allOfConditions, notCondition

				function convertNode(node) {
					let listOperation = matchValue.literal(typeOf(node), {
						anyOfConditions: operations.anyOf,
						allOfConditions: operations.allOf,
						notCondition: null,
						condition: null
					});

					if (listOperation != null) {
						return listOperation(node.items.map((item) => convertNode(item)));
					} else if (typeOf(node) === "notCondition") {
						return operations.not(convertNode(node.condition));
					} else if (typeOf(node) === "condition") {
						return operations.expression({
							left: rootNode.left,
							condition: node
						});
					} else {
						unreachable(`Encountered node type '${node.type}' within condition modifier`);
					}
				}

				return convertNode(rootNode.condition);
			}
		}
	}
};
