"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.conditionalOutput = exports.def = exports.imp = exports.joinCode = exports.arrayOf = exports.literalOf = exports.code = exports.Import = exports.Code = void 0;
const Import_1 = require("./Import");
const Code_1 = require("./Code");
const ConditionalOutput_1 = require("./ConditionalOutput");
const is_plain_object_1 = require("./is-plain-object");
const Literal_1 = require("./Literal");
var Code_2 = require("./Code");
Object.defineProperty(exports, "Code", { enumerable: true, get: function () { return Code_2.Code; } });
var Import_2 = require("./Import");
Object.defineProperty(exports, "Import", { enumerable: true, get: function () { return Import_2.Import; } });
/** A template literal to format code and auto-organize imports. */
function code(literals, ...placeholders) {
    return new Code_1.Code(literals, placeholders.map((p) => {
        if (is_plain_object_1.isPlainObject(p)) {
            return literalOf(p);
        }
        else {
            return p;
        }
    }));
}
exports.code = code;
function literalOf(object) {
    return new Literal_1.Literal(object);
}
exports.literalOf = literalOf;
function arrayOf(...elements) {
    return literalOf(elements);
}
exports.arrayOf = arrayOf;
function joinCode(chunks, opts = {}) {
    const { on = '', trim = true } = opts;
    const literals = [''];
    for (let i = 0; i < chunks.length - 1; i++) {
        literals.push(on);
    }
    literals.push('');
    if (trim) {
        chunks.forEach((c) => (c.trim = true));
    }
    return new Code_1.Code(literals, chunks);
}
exports.joinCode = joinCode;
/** Creates an import that will be auto-imported at the top of the output file. */
function imp(spec, opts = {}) {
    const sym = Import_1.Import.from(spec);
    if (opts && opts.definedIn) {
        sym.definedIn = opts.definedIn;
    }
    return sym;
}
exports.imp = imp;
/** Defines `symbol` as being locally defined in the file, to avoid import collisions. */
function def(symbol) {
    return new Code_1.Def(symbol);
}
exports.def = def;
/** Creates a conditionally-output code snippet. */
function conditionalOutput(usageSite, declarationSite) {
    return new ConditionalOutput_1.ConditionalOutput(usageSite, declarationSite);
}
exports.conditionalOutput = conditionalOutput;
