"use strict";
const {
	parse,
	types,
	traverse,
	loadOptions,
} = require("@babel/core");
const getTemplate = require("./get-template");
const loadSyntax = require("postcss-syntax/load-syntax");

const isStyleSheetCreate = expectAdjacentSibling(["create"]);
const supports = {
	// import styled from '@emotion/styled'
	// import { styled } from 'glamor/styled'
	// import { styled } from "styletron-react";
	// import { styled } from 'linaria/react';
	styled: true,

	// import { style } from "typestyle";
	style: true,

	// import { StyleSheet, css } from 'aphrodite';
	// import styled, { css } from 'astroturf';
	// import { css } from 'lit-css';
	// import { css } from 'glamor'
	// require('css-light').css({color: 'red'});
	// import { css } from 'linaria';
	css: true,

	// import { StyleSheet, css } from 'aphrodite';
	// import { AppRegistry, StyleSheet, Text, View } from 'react-native';
	StyleSheet: isStyleSheetCreate,

	// import styled, { css } from 'astroturf';
	astroturf: true,

	// require('csjs')`css`;
	csjs: true,

	// require('cssobj')({color: 'red'})
	cssobj: true,

	// require('electron-css')({color: 'red'})
	"electron-css": true,

	// import styled from "react-emotion";
	"react-emotion": true,

	// import styled from 'preact-emotion'
	"preact-emotion": true,

	// https://github.com/streamich/freestyler
	freestyler: true,

	// https://github.com/paypal/glamorous
	glamorous: true,

	// https://github.com/irom-io/i-css
	// "i-css": (i, nameSpace) => nameSpace[i + 1] === "addStyles" && nameSpace[i + 2] === "wrapper",

	// https://github.com/j2css/j2c
	j2c: expectAdjacentSibling(["inline", "sheet"]),

	// var styles = StyleSheet.create({color: 'red'})
	"react-inline": isStyleSheetCreate,
	"react-style": isStyleSheetCreate,

	// import reactCSS from 'reactcss'
	reactcss: true,

	// const StyledButton = injectSheet(styles)(Button)
	"react-jss": true,

	// import styled from 'styled-components';
	"styled-components": true,

	// import {withStyle} from "styletron-react";
	"styletron-react": expectAdjacentSibling(["withStyle"]),

	"styling": true,

	// const rule = superstyle({ color: 'blue' })
	"superstyle": true,
};

const plugins = [
	"jsx",
	"typescript",
	"objectRestSpread",
	["decorators", { "decoratorsBeforeExport": false }],
	"classProperties",
	"exportExtensions",
	"asyncGenerators",
	"functionBind",
	"functionSent",
	"dynamicImport",
	"optionalCatchBinding",
];

function expectAdjacentSibling (names) {
	return (i, nameSpace) => (
		names.some(name => nameSpace[i + 1] === name)
	);
}

function loadBabelOpts (opts) {
	const filename = opts.from && opts.from.replace(/\?.*$/, "");
	opts = {
		sourceFilename: filename,
		sourceType: filename && /\.m[tj]sx?$/.test(filename) ? "module" : "unambiguous",
		plugins,
		allowImportExportEverywhere: true,
		allowAwaitOutsideFunction: true,
		allowReturnOutsideFunction: true,
		allowSuperOutsideMethod: true,
	};
	let fileOpts;
	try {
		fileOpts = filename && loadOptions({
			filename,
		});
	} catch (ex) {
		//
	}
	for (const key in fileOpts) {
		if (Array.isArray(fileOpts[key]) && !fileOpts[key].length) {
			continue;
		}
		opts[key] = fileOpts[key];
	}
	return opts;
}

function literalParser (source, opts, styles) {
	let ast;
	try {
		ast = parse(source, {
			parserOpts: loadBabelOpts(opts),
		});
	} catch (ex) {
		// console.error(ex);
		return styles || [];
	}

	const specifiers = new Map();
	const variableDeclarator = new Map();
	let objLiteral = new Set();
	let tplLiteral = new Set();
	const tplCallee = new Set();
	const jobs = [];

	function addObjectJob (path) {
		jobs.push(() => {
			addObjectValue(path);
		});
	}

	function addObjectValue (path) {
		if (path.isIdentifier()) {
			const identifier = path.scope.getBindingIdentifier(path.node.name);
			if (identifier) {
				path = variableDeclarator.get(identifier);
				if (path) {
					variableDeclarator.delete(identifier);
					path.forEach(addObjectExpression);
				}
			}
		} else {
			addObjectExpression(path);
		}
	}

	function addObjectExpression (path) {
		if (path.isObjectExpression()) {
			path.get("properties").forEach(prop => {
				if (prop.isSpreadElement()) {
					addObjectValue(prop.get("argument"));
				}
			});
			objLiteral.add(path.node);
			return path;
		}
	}

	function setSpecifier (id, nameSpace) {
		nameSpace.unshift.apply(
			nameSpace,
			nameSpace.shift().replace(/^\W+/, "").split(/[/\\]+/g)
		);

		if (types.isIdentifier(id)) {
			specifiers.set(id.name, nameSpace);
			specifiers.set(id, nameSpace);
		} else if (types.isObjectPattern(id)) {
			id.properties.forEach(property => {
				if (types.isObjectProperty(property)) {
					const key = property.key;
					nameSpace = nameSpace.concat(key.name || key.value);
					id = property.value;
				} else {
					id = property.argument;
				}
				setSpecifier(id, nameSpace);
			});
		} else if (types.isArrayPattern(id)) {
			id.elements.forEach((element, i) => {
				setSpecifier(element, nameSpace.concat(String(i)));
			});
		}
	}

	function getNameSpace (path, nameSpace) {
		let node = path.node;
		if (path.isIdentifier() || path.isJSXIdentifier()) {
			node = path.scope.getBindingIdentifier(node.name) || node;
			const specifier = specifiers.get(node) || specifiers.get(node.name);
			if (specifier) {
				nameSpace.unshift.apply(nameSpace, specifier);
			} else {
				nameSpace.unshift(node.name);
			}
		} else {
			[
				"name",
				"property",
				"object",
				"callee",
			].forEach(prop => {
				node[prop] && getNameSpace(path.get(prop), nameSpace);
			});
		}

		return nameSpace;
	}

	function isStylePath (path) {
		return getNameSpace(path, []).some(function (name) {
			let result = name && ((supports.hasOwnProperty(name) && supports[name]) || (opts.syntax.config.hasOwnProperty(name) && opts.syntax.config[name]));
			switch (typeof result) {
				case "function": {
					result = result.apply(this, Array.prototype.slice.call(arguments, 1));
				}
				// eslint-disable-next-line no-fallthrough
				case "boolean": {
					return result;
				}
			}
		});
	}

	const visitor = {
		ImportDeclaration: (path) => {
			const moduleId = path.node.source.value;
			path.node.specifiers.forEach(specifier => {
				const nameSpace = [moduleId];
				if (specifier.imported) {
					nameSpace.push(specifier.imported.name);
				}
				setSpecifier(specifier.local, nameSpace);
			});
		},
		JSXAttribute: (path) => {
			if (/^(?:css|style)$/.test(path.node.name.name)) {
				addObjectJob(path.get("value.expression"));
			}
		},
		VariableDeclarator: (path) => {
			variableDeclarator.set(path.node.id, path.node.init ? [path.get("init")] : []);
		},
		AssignmentExpression: (path) => {
			if (types.isIdentifier(path.node.left) && types.isObjectExpression(path.node.right)) {
				const identifier = path.scope.getBindingIdentifier(path.node.left.name);
				const variable = variableDeclarator.get(identifier);
				const valuePath = path.get("right");
				if (variable) {
					variable.push(valuePath);
				} else {
					variableDeclarator.set(identifier, [valuePath]);
				}
			}
		},
		CallExpression: (path) => {
			const callee = path.node.callee;
			if (types.isIdentifier(callee, { name: "require" }) && !path.scope.getBindingIdentifier(callee.name)) {
				path.node.arguments.filter(types.isStringLiteral).forEach(arg => {
					const moduleId = arg.value;
					const nameSpace = [moduleId];
					let currPath = path;
					do {
						let id = currPath.parent.id;
						if (!id) {
							id = currPath.parent.left;
							if (id) {
								id = path.scope.getBindingIdentifier(id.name) || id;
							} else {
								if (types.isIdentifier(currPath.parent.property)) {
									nameSpace.push(currPath.parent.property.name);
								}
								currPath = currPath.parentPath;
								continue;
							}
						};
						setSpecifier(id, nameSpace);
						break;
					} while (currPath);
				});
			} else if (!tplCallee.has(callee) && isStylePath(path.get("callee"))) {
				path.get("arguments").forEach((arg) => {
					addObjectJob(arg.isFunction() ? arg.get("body") : arg);
				});
			}
		},
		TaggedTemplateExpression: (path) => {
			if (isStylePath(path.get("tag"))) {
				tplLiteral.add(path.node.quasi);
				if (path.node.tag.callee) {
					tplCallee.add(path.node.tag.callee);
				}
			}
		},
	};

	traverse(ast, visitor);
	jobs.forEach(job => job());

	objLiteral = Array.from(objLiteral).map(endNode => {
		const objectSyntax = require("./object-syntax");
		let startNode = endNode;
		if (startNode.leadingComments && startNode.leadingComments.length) {
			startNode = startNode.leadingComments[0];
		}
		let startIndex = startNode.start;
		const before = source.slice(startNode.start - startNode.loc.start.column, startNode.start);
		if (/^\s+$/.test(before)) {
			startIndex -= before.length;
		}
		return {
			startIndex,
			endIndex: endNode.end,
			skipConvert: true,
			content: source,
			opts: {
				node: endNode,
			},
			syntax: objectSyntax,
			lang: "object-literal",
		};
	});

	tplLiteral = Array.from(tplLiteral).filter(node => (
		objLiteral.every(style => (
			node.start > style.endIndex || node.end < style.startIndex
		))
	)).map(node => {
		const quasis = node.quasis.map(node => ({
			start: node.start,
			end: node.end,
		}));
		const style = {
			startIndex: quasis[0].start,
			endIndex: quasis[quasis.length - 1].end,
			content: getTemplate(node, source),
		};
		if (node.expressions.length) {
			style.syntax = loadSyntax(opts, __dirname);
			style.lang = "template-literal";
			style.opts = {
				quasis: quasis,
			};
		} else {
			style.lang = "css";
		}
		return style;
	});

	return (styles || []).concat(objLiteral).concat(tplLiteral);
};

module.exports = literalParser;
