"use strict";
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
    if (k2 === undefined) k2 = k;
    Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });
}) : (function(o, m, k, k2) {
    if (k2 === undefined) k2 = k;
    o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
    Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
    o["default"] = v;
});
var __importStar = (this && this.__importStar) || function (mod) {
    if (mod && mod.__esModule) return mod;
    var result = {};
    if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
    __setModuleDefault(result, mod);
    return result;
};
Object.defineProperty(exports, "__esModule", { value: true });
const experimental_utils_1 = require("@typescript-eslint/experimental-utils");
const util = __importStar(require("../util"));
exports.default = util.createRule({
    name: 'consistent-type-definitions',
    meta: {
        type: 'suggestion',
        docs: {
            description: 'Consistent with type definition either `interface` or `type`',
            category: 'Stylistic Issues',
            // too opinionated to be recommended
            recommended: false,
        },
        messages: {
            interfaceOverType: 'Use an `interface` instead of a `type`.',
            typeOverInterface: 'Use a `type` instead of an `interface`.',
        },
        schema: [
            {
                enum: ['interface', 'type'],
            },
        ],
        fixable: 'code',
    },
    defaultOptions: ['interface'],
    create(context, [option]) {
        const sourceCode = context.getSourceCode();
        return {
            "TSTypeAliasDeclaration[typeAnnotation.type='TSTypeLiteral']"(node) {
                if (option === 'interface') {
                    context.report({
                        node: node.id,
                        messageId: 'interfaceOverType',
                        fix(fixer) {
                            var _a;
                            const typeNode = (_a = node.typeParameters) !== null && _a !== void 0 ? _a : node.id;
                            const fixes = [];
                            const firstToken = sourceCode.getFirstToken(node);
                            if (firstToken) {
                                fixes.push(fixer.replaceText(firstToken, 'interface'));
                                fixes.push(fixer.replaceTextRange([typeNode.range[1], node.typeAnnotation.range[0]], ' '));
                            }
                            const afterToken = sourceCode.getTokenAfter(node.typeAnnotation);
                            if (afterToken &&
                                afterToken.type === experimental_utils_1.AST_TOKEN_TYPES.Punctuator &&
                                afterToken.value === ';') {
                                fixes.push(fixer.remove(afterToken));
                            }
                            return fixes;
                        },
                    });
                }
            },
            TSInterfaceDeclaration(node) {
                if (option === 'type') {
                    context.report({
                        node: node.id,
                        messageId: 'typeOverInterface',
                        fix(fixer) {
                            var _a;
                            const typeNode = (_a = node.typeParameters) !== null && _a !== void 0 ? _a : node.id;
                            const fixes = [];
                            const firstToken = sourceCode.getFirstToken(node);
                            if (firstToken) {
                                fixes.push(fixer.replaceText(firstToken, 'type'));
                                fixes.push(fixer.replaceTextRange([typeNode.range[1], node.body.range[0]], ' = '));
                            }
                            if (node.extends) {
                                node.extends.forEach(heritage => {
                                    const typeIdentifier = sourceCode.getText(heritage);
                                    fixes.push(fixer.insertTextAfter(node.body, ` & ${typeIdentifier}`));
                                });
                            }
                            return fixes;
                        },
                    });
                }
            },
        };
    },
});
//# sourceMappingURL=consistent-type-definitions.js.map