text: "use strict";
  Object.defineProperty(exports, "__esModule", { value: true });
  var tslib_1 = require("tslib");
  var errors = require("../../errors");
  var manipulation_1 = require("../../manipulation");
  var typescript_1 = require("../../typescript");
  var utils_1 = require("../../utils");
  var statement_1 = require("../statement");
  var ExportDeclaration = /** @class */ (function (_super) {
      tslib_1.__extends(ExportDeclaration, _super);
      function ExportDeclaration() {
          return _super !== null && _super.apply(this, arguments) || this;
      }
      ExportDeclaration.prototype.setModuleSpecifier = function (textOrSourceFile) {
          var text = typeof textOrSourceFile === "string" ? textOrSourceFile : this.sourceFile.getRelativePathAsModuleSpecifierTo(textOrSourceFile);
          var stringLiteral = this.getModuleSpecifier();
          if (stringLiteral == null) {
              var semiColonToken = this.getLastChildIfKind(typescript_1.SyntaxKind.SemicolonToken);
              var quoteKind = this.global.manipulationSettings.getQuoteKind();
              manipulation_1.insertIntoParentTextRange({
                  insertPos: semiColonToken != null ? semiColonToken.getPos() : this.getEnd(),
                  parent: this,
                  newText: " from " + quoteKind + text + quoteKind
              });
          }
          else
              stringLiteral.setLiteralValue(text);
          return this;
      };
      /**
       * Gets the module specifier or undefined if it doesn't exist.
       */
      ExportDeclaration.prototype.getModuleSpecifier = function () {
          var moduleSpecifier = this.getNodeFromCompilerNodeIfExists(this.compilerNode.moduleSpecifier);
          if (moduleSpecifier == null)
              return undefined;
          if (!utils_1.TypeGuards.isStringLiteral(moduleSpecifier))
              throw new errors.InvalidOperationError("Expected the module specifier to be a string literal.");
          return moduleSpecifier;
      };
      /**
       * Gets the module specifier value or undefined if it doesn't exist.
       */
      ExportDeclaration.prototype.getModuleSpecifierValue = function () {
          var moduleSpecifier = this.getModuleSpecifier();
          return moduleSpecifier == null ? undefined : moduleSpecifier.getLiteralValue();
      };
      /**
       * Gets the source file referenced in the module specifier or throws if it can't find it or it doesn't exist.
       */
      ExportDeclaration.prototype.getModuleSpecifierSourceFileOrThrow = function () {
          return errors.throwIfNullOrUndefined(this.getModuleSpecifierSourceFile(), "A module specifier source file was expected.");
      };
      /**
       * Gets the source file referenced in the module specifier.
       */
      ExportDeclaration.prototype.getModuleSpecifierSourceFile = function () {
          var stringLiteral = this.getLastChildByKind(typescript_1.SyntaxKind.StringLiteral);
          if (stringLiteral == null)
              return undefined;
          var symbol = stringLiteral.getSymbol();
          if (symbol == null)
              return undefined;
          var declarations = symbol.getDeclarations();
          if (declarations.length === 0 || declarations[0].getKind() !== typescript_1.SyntaxKind.SourceFile)
              return undefined;
          return declarations[0];
      };
      /**
       * Gets if the module specifier starts with `./` or `../`.
       */
      ExportDeclaration.prototype.isModuleSpecifierRelative = function () {
          var moduleSpecifierValue = this.getModuleSpecifierValue();
          if (moduleSpecifierValue == null)
              return false;
          return utils_1.ModuleUtils.isModuleSpecifierRelative(moduleSpecifierValue);
      };
      /**
       * Gets if the module specifier exists
       */
      ExportDeclaration.prototype.hasModuleSpecifier = function () {
          return this.getLastChildByKind(typescript_1.SyntaxKind.StringLiteral) != null;
      };
      /**
       * Gets if this export declaration is a namespace export.
       */
      ExportDeclaration.prototype.isNamespaceExport = function () {
          return !this.hasNamedExports();
      };
      /**
       * Gets if the export declaration has named exports.
       */
      ExportDeclaration.prototype.hasNamedExports = function () {
          return this.compilerNode.exportClause != null;
      };
      ExportDeclaration.prototype.addNamedExport = function (structureOrName) {
          return this.addNamedExports([structureOrName])[0];
      };
      /**
       * Adds named exports.
       * @param structuresOrNames - Structures or names that represent the named exports.
       */
      ExportDeclaration.prototype.addNamedExports = function (structuresOrNames) {
          return this.insertNamedExports(this.getNamedExports().length, structuresOrNames);
      };
      ExportDeclaration.prototype.insertNamedExport = function (index, structureOrName) {
          return this.insertNamedExports(index, [structureOrName])[0];
      };
      /**
       * Inserts named exports into the export declaration.
       * @param index - Index to insert at.
       * @param structuresOrNames - Structures or names that represent the named exports.
       */
      ExportDeclaration.prototype.insertNamedExports = function (index, structuresOrNames) {
          if (utils_1.ArrayUtils.isNullOrEmpty(structuresOrNames))
              return [];
          var namedExports = this.getNamedExports();
          var writer = this.getWriterWithQueuedChildIndentation();
          var namedExportStructurePrinter = this.global.structurePrinterFactory.forNamedImportExportSpecifier();
          index = manipulation_1.verifyAndGetIndex(index, namedExports.length);
          if (namedExports.length === 0) {
              namedExportStructurePrinter.printTextsWithBraces(writer, structuresOrNames);
              var asteriskToken = this.getFirstChildByKindOrThrow(typescript_1.SyntaxKind.AsteriskToken);
              manipulation_1.insertIntoParentTextRange({
                  insertPos: asteriskToken.getStart(),
                  parent: this,
                  newText: writer.toString(),
                  replacing: {
                      textLength: 1
                  }
              });
          }
          else {
              namedExportStructurePrinter.printTexts(writer, structuresOrNames);
              manipulation_1.insertIntoCommaSeparatedNodes({
                  parent: this.getFirstChildByKindOrThrow(typescript_1.SyntaxKind.NamedExports).getFirstChildByKindOrThrow(typescript_1.SyntaxKind.SyntaxList),
                  currentNodes: namedExports,
                  insertIndex: index,
                  newText: writer.toString(),
                  surroundWithSpaces: this.global.getFormatCodeSettings().insertSpaceAfterOpeningAndBeforeClosingNonemptyBraces
              });
          }
          return manipulation_1.getNodesToReturn(this.getNamedExports(), index, structuresOrNames.length);
      };
      /**
       * Gets the named exports.
       */
      ExportDeclaration.prototype.getNamedExports = function () {
          var _this = this;
          var namedExports = this.compilerNode.exportClause;
          if (namedExports == null)
              return [];
          return namedExports.elements.map(function (e) { return _this.getNodeFromCompilerNode(e); });
      };
      /**
       * Changes the export declaration to namespace export. Removes all the named exports.
       */
      ExportDeclaration.prototype.toNamespaceExport = function () {
          if (!this.hasModuleSpecifier())
              throw new errors.InvalidOperationError("Cannot change to a namespace export when no module specifier exists.");
          var namedExportsNode = this.getFirstChildByKind(typescript_1.SyntaxKind.NamedExports);
          if (namedExportsNode == null)
              return this;
          manipulation_1.insertIntoParentTextRange({
              parent: this,
              newText: "*",
              insertPos: namedExportsNode.getStart(),
              replacing: {
                  textLength: namedExportsNode.getWidth()
              }
          });
          return this;
      };
      return ExportDeclaration;
  }(statement_1.Statement));
  exports.ExportDeclaration = ExportDeclaration;
  