"use strict";
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
    function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
    return new (P || (P = Promise))(function (resolve, reject) {
        function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
        function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
        function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
        step((generator = generator.apply(thisArg, _arguments || [])).next());
    });
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.setUpStyles = void 0;
const ts = require("typescript");
const schematics_1 = require("@angular-devkit/schematics");
const ast_1 = require("../utils/ast");
const vendored_ast_utils_1 = require("./vendored-ast-utils");
const get_app_component_path_1 = require("./get-app-component-path");
const STYLES = `\n\nconst STYLES = (_theme: ThemeVariables, ref: ThemeRef) => {
  const __ = ref.selectorsOf(STYLES);
  return {
    root: lyl \`{
      display: block
    }\`
  };
};`;
/** Adds the styles to the src/app/app.component.ts file. */
function setUpStyles(options, filePath, decorator = 'Component', content = STYLES) {
    return (host, _context) => __awaiter(this, void 0, void 0, function* () {
        if (!filePath) {
            filePath = yield get_app_component_path_1.getAppComponentPath(host, options);
        }
        const buffer = host.read(filePath);
        if (buffer === null) {
            throw new schematics_1.SchematicsException(`Could not read index file: ${filePath}`);
        }
        // add import style
        ast_1.addImport(host, filePath, ['ThemeVariables', 'ThemeRef', 'lyl'], '@alyle/ui');
        ast_1.addProvider(host, filePath, decorator, 'StyleRenderer', '@alyle/ui');
        let component = getComponentOrDirective(host, filePath);
        const componentStartPos = component.decorators[0].pos;
        const recorder = host.beginUpdate(filePath);
        recorder.insertLeft(componentStartPos, content);
        host.commitUpdate(recorder);
        component = getComponentOrDirective(host, filePath);
        const hasConstructor = component.members
            .some(prop => (prop.kind === ts.SyntaxKind.Constructor) && !!prop.body);
        let constructor;
        let __recorder = host.beginUpdate(filePath);
        const propertyValue = `\n  readonly classes = this.sRenderer.renderSheet(STYLES, true);\n`;
        const constructorCall = `  constructor(\n    readonly sRenderer: StyleRenderer\n  ) { }\n`;
        const OpenBraceTokenPos = vendored_ast_utils_1.findNodes(component, ts.SyntaxKind.OpenBraceToken)
            .filter(prop => prop.parent === component).map(prop => prop.end)[0];
        __recorder.insertLeft(OpenBraceTokenPos, propertyValue);
        host.commitUpdate(__recorder);
        __recorder = host.beginUpdate(filePath);
        component = getComponentOrDirective(host, filePath);
        if (hasConstructor) {
            constructor = getContructor(component);
            const pos = vendored_ast_utils_1.findNodes(constructor, ts.SyntaxKind.OpenParenToken)
                .filter(prop => prop.parent === constructor).map(prop => prop.end)[0];
            if (constructor.parameters.length) {
                __recorder.insertLeft(pos, `\n    readonly sRenderer: StyleRenderer,\n  `);
            }
            else {
                __recorder.insertLeft(pos, `\n    readonly sRenderer: StyleRenderer\n  `);
            }
        }
        else if (component.members.length) {
            const latestPropertyDeclarationEnd = component.members
                .filter(prop => prop.kind === ts.SyntaxKind.PropertyDeclaration)
                .map(({ end }) => end).reverse()[0];
            __recorder.insertLeft(latestPropertyDeclarationEnd, `\n\n${constructorCall}`);
        }
        else {
            __recorder.insertLeft(OpenBraceTokenPos, constructorCall);
        }
        host.commitUpdate(__recorder);
        component = getComponentOrDirective(host, filePath);
        constructor = getContructor(component);
        ast_1.prettierConstructorParameters(host, filePath, constructor);
        // return host;
    });
}
exports.setUpStyles = setUpStyles;
function getComponentOrDirective(host, filePath) {
    const fileSource = ast_1.getTsSourceFile(host, filePath);
    return vendored_ast_utils_1.findNodes(fileSource, ts.SyntaxKind.ClassDeclaration, 1)
        .filter(prop => prop.decorators)
        .filter(prop => prop.decorators.filter(decorator => decorator.getText().startsWith('@Component') ||
        decorator.getText().startsWith('@Directive')))[0];
}
function getContructor(componentOrDirective) {
    return componentOrDirective.members
        .filter(prop => prop.kind === ts.SyntaxKind.Constructor)[0];
}
//# sourceMappingURL=styles.js.map