/**
 * @license
 * Copyright (c) 2020, 2023 Oracle and/or its affiliates.
 * Licensed under The Universal Permissive License (UPL), Version 1.0
 * as shown at https://oss.oracle.com/licenses/upl/
 * @ignore
 */

 declare namespace ojaf {

  /**
   * General Interface for a rule
   */
  export interface AuditRule {
    getName(): string,
    getShortDescription(): string,
    getDescription(): string,
    register(context: RegisterContext): ListenerSet,
    onMsg?(sender: MessageSender, data: Array<any>)
  }

  // Supporting Types for auditRule

  export interface MessageSender {
    sender: string,
    regType: AST_NODE_TYPE|DOM_NODE_TYPE|JSON_NODE_TYPE
  }

  /**
   * The key  registration context that is passed to the register function by JAF
   */
  export interface RegisterContext {
    rulePack: RulePack,
    ruleOpts: RuleOptions,
    runMode: 'cli' | 'api' | 'amd' | 'ojet',
    config: JafConfig,
    ojetConfig: object, //TODO
    utils: ContextUtils,
    sysOpts: SysOpts,
    jsNodeTypes: any
  }

  // Supporting types and interfaces for the registerContext

  export interface RulePack {
    getPackInfo(): RulePackInfo,
    getRuleCustomOptions(ruleName?: string, prefix?: string): RuleOptions,
    getRuleCustomOption(property: string, ruleName?: string, prefix?: string): any,
    getRuleOptions(ruleName?: string, prefix?: string): RuleOptions,
    getRuleOption(property: string, ruleName?: string, prefix?: string): any,
    getPrefix(): string,
    setRuleOptions(ruleName: string, options: RuleOptions): boolean, //TODO Check is rule-name really optional?
    isRuleEnabled(ruleName: string, prefix?: string): boolean,
    isRuleDisabled(ruleName: string, prefix?: string): boolean,
    disableRule(ruleName: string): boolean,
    enableRule(ruleName: string): boolean,
    getRuleCount(): number,
    getEnabledRuleCount(): number,
    getRuleList(): Array<string>,
    getEnabledRuleList(): Array<string>,
    getRule(): object,
    getExtension(): any,
    setExtension(data: any): void,
    sendMsg(ruleName: string, ...data: any): any,
    broadcastMsg(ruleNames: Array<string>, ...data: any): number
  }

  export interface RulePackInfo {
    path: string,
    prefix: string,
    title: string,
    version: string,
    status: Array<string>,
    packData: any
  }

  export interface RuleOptions {
    [key: string]: any
  }

  export interface JafConfig {
    rulePacks?: Array<ConfigRulePackDef>,
    ruleMods?: any, //TODO
    builtinJetRules?: boolean,
    builtinJetWcRules?: boolean,
    builtinJetWcOracleRules: boolean,
    severity?: string,
    sevMap?: any, //TODO
    groups?: string | Array<string>,
    defGroups?: Array<ConfigGroupDef>,
    ruleNames?: Array<string>,
    base: string,
    files: Array<string | ConfigFilesDef>,
    exclude?: Array<string | ConfigFilesDef>,
    jetPagesOnly?: boolean,
    theme: 'redwood' | 'alta' | 'none',
    format: 'prose'  | 'json' | 'line',
    proseFormat?: string,
    lineFormat?: string,
    outPath?: string
  }

  export interface ConfigRulePackDef {
    path: string,
    enabled: boolean,
    status?: Array<string>
  }

  export interface ConfigGroupDef {
    [key: string]: Array<string>
  }

  export interface ConfigFilesDef {
    base: string,
    files: Array<string>
  }


  export interface SysOpts {
    verboseMode: boolean,
    debugMode: boolean
  }


  //  Types to support ListenerSet ----------------------------------------------------
  export interface ListenerSet {
    "startup"?:     RuleListener,
    "closedown"?:   RuleListener,
    "startaudit"?:  RuleListener,
    "endaudit"?:    RuleListener,
    "startupRP"?:   RuleListener,
    "closedownRP"?: RuleListener,
    "webcomp"?:     ElementListener,
    "elem"?:        ElementListener,
    "tag"?:         ElementListener,
    "ojtag"?:       ElementListener,
    "script"?:      ElementListener,
    "link"?:        ElementListener,
    [tagName:`<${string}>`]:ElementListener,
    "attr"?:        AttrListener,
    "attrexpr"?:    AttrListener,
    "class"?:       AttrListener,
    "style"?:       AttrListener,
    "type"?:        AttrListener,
    "event"?:       EventListener,
    "comment"?:     CommentListener,
    "doctype"?:     DocTypeListener,
    "procstmt"?:    StatementListener,
    "directive"?:   StatementListener,
    "json"?:        JsonListener,
    "compjson"?:    JsonListener,
    "file"?:        FileListener,
    "endfile"?:     FileListener,
    "startscript"?: FileListener,
    "endscript"?:   FileListener,
    "AssignmentExpression"?: AstListener,
    "AssignmentPattern"?: AstListener,
    "ArrayExpression"?: AstListener,
    "ArrayPattern"?: AstListener,
    "ArrowFunctionExpression"?: AstListener,
    "AwaitExpression"?: AstListener,
    "BlockStatement"?: AstListener,
    "BinaryExpression"?: AstListener,
    "BreakStatement"?: AstListener,
    "CallExpression"?: AstListener,
    "CatchClause"?: AstListener,
    "ClassBody"?: AstListener,
    "ClassDeclaration"?: AstListener,
    "ClassExpression"?: AstListener,
    "ConditionalExpression"?: AstListener,
    "ContinueStatement"?: AstListener,
    "DoWhileStatement"?: AstListener,
    "DebuggerStatement"?: AstListener,
    "EmptyStatement"?: AstListener,
    "ExperimentalRestProperty"?: AstListener,
    "ExperimentalSpreadProperty"?: AstListener,
    "ExpressionStatement"?: AstListener,
    "ForStatement"?: AstListener,
    "ForInStatement"?: AstListener,
    "ForOfStatement"?: AstListener,
    "FunctionDeclaration"?: AstListener,
    "FunctionExpression"?: AstListener,
    "Identifier"?: AstListener,
    "IfStatement"?: AstListener,
    "Literal"?: AstListener,
    "LabeledStatement"?: AstListener,
    "LogicalExpression"?: AstListener,
    "MemberExpression"?: AstListener,
    "MetaProperty"?: AstListener,
    "MethodDefinition"?: AstListener,
    "NewExpression"?: AstListener,
    "ObjectExpression"?: AstListener,
    "ObjectPattern"?: AstListener,
    "Program"?: AstListener,
    "Property"?: AstListener,
    "RestElement"?: AstListener,
    "ReturnStatement"?: AstListener,
    "SequenceExpression"?: AstListener,
    "SpreadElement"?: AstListener,
    "Super"?: AstListener,
    "SwitchCase"?: AstListener,
    "SwitchStatement"?: AstListener,
    "TaggedTemplateExpression"?: AstListener,
    "TemplateElement"?: AstListener,
    "TemplateLiteral"?: AstListener,
    "ThisExpression"?: AstListener,
    "ThrowStatement"?: AstListener,
    "TryStatement"?: AstListener,
    "UnaryExpression"?: AstListener,
    "UpdateExpression"?: AstListener,
    "VariableDeclaration"?: AstListener,
    "VariableDeclarator"?: AstListener,
    "WhileStatement"?: AstListener,
    "WithStatement"?: AstListener,
    "YieldExpression"?: AstListener,
    "JSXIdentifier"?: AstListener,
    "JSXNamespacedName"?: AstListener,
    "JSXMemberExpression"?: AstListener,
    "JSXEmptyExpression"?: AstListener,
    "JSXExpressionContainer"?: AstListener,
    "JSXElement"?: AstListener,
    "JSXClosingElement"?: AstListener,
    "JSXOpeningElement"?: AstListener,
    "JSXAttribute"?: AstListener,
    "JSXSpreadAttribute"?: AstListener,
    "JSXText"?: AstListener,
    "ExportDefaultDeclaration"?: AstListener,
    "ExportNamedDeclaration"?: AstListener,
    "ExportAllDeclaration"?: AstListener,
    "ExportSpecifier"?: AstListener,
    "ImportDeclaration"?: AstListener,
    "ImportSpecifier"?: AstListener,
    "ImportDefaultSpecifier"?: AstListener,
    "ImportNamespaceSpecifier"?: AstListener,
    "TSImportEqualsDeclaration"?:AstListener,
    "css-sheet"?: CssListener,
    "css-rule"?: CssListener,
    "css-atrule"?: CssAtRuleListener,
    "css-@media"?: CssAtRuleListener,
    "css-@keyframes"?: CssAtRuleListener,
    "css-@charset"?: CssAtRuleListener,
    "css-@import"?: CssAtRuleListener,
    "css-@namespace"?: CssAtRuleListener,
    "css-@supports"?: CssAtRuleListener,
    "css-@page"?: CssAtRuleListener,
    "css-@font-face"?: CssAtRuleListener,
    "css-selector"?: CssListener,
    "css-sel-type"?: CssListener,
    "css-sel-id"?: CssListener,
    "css-sel-pseudo"?: CssListener
  }

   // Rule Listener Contexts -----------------------------------------------------------

   export interface RuleListenerContext {
    Issue: any, //TODO
    ojetConfig?:object, //TODO
    phase: string,
    type:string,
    sysOpts:SysOpts,
    utils: ContextUtils,
    reporter: IssueReporter,
    ruleName:string,
    rulePack:RulePack
  }

  /**
   * Base listener context containing all of the common attributes
   */
  export interface AuditListenerContext {
    data: string,
    Issue: any, //TODO
    rawData: string,
    suppData: SuppData,
    type:string,
    utils: ContextUtils,
    reporter: IssueReporter,
    ruleName:string,
    rulePack:RulePack,
    filepath:string
  }

  export interface LifecycleListener {(context:RegisterContext): null|boolean}
  export interface RuleListener {(context:RuleListenerContext): null|boolean}
  export interface ElementListener {(context: ElementListenerContext, elementName: string): void}
  export interface AttrListener {(context: ElementListenerContext, name: string,value: string|Array<string>, rawValue: string): void}
  export interface EventListener {(context: ElementListenerContext, event:string,eventValue:EventListenerValue): void}
  export interface CommentListener {(context: ElementListenerContext, comment:string): void}
  export interface DocTypeListener {(context: ElementListenerContext, doctype:string, value:string): void}
  export interface StatementListener {(context: ElementListenerContext, statement:string, value:string): void}
  export interface ElementListenerContext extends AuditListenerContext {
    tag: string,
    node: DomNode,
    tagNode: DomNode,
    position: {line?:number, col?:number, start?:number, end?:number},
    elemStack: Array<DomNode>,
    ojTag: boolean,
    ojNS?: boolean
  }

  export interface JsonListener {(context: JsonListenerContext, JsonNode:JsonNode): void}
  export interface JsonListenerContext extends AuditListenerContext {
    filetype?:string,
    node:JsonNode,
    ruleName:string,
    rulePack:RulePack,
    position?: number
  }

  export interface FileListener {(context: FileListenerContext): boolean}
  export interface FileListenerContext extends AuditListenerContext {
    phase:string,
    filename:string,
    filetype:string,
    position:{line:number, col:number},
    node:DomNode|AstNode|JsonNode|CssNode
  }

  export interface AstListener {(context: AstListenerContext, node:AstNode): void}
  export interface AstListenerContext extends AuditListenerContext {
    node:AstNode,
    position:{offset:number, start:number, end:number}
  }


  export interface CssListener {(context: CssListenerContext, node:CssNode): void}
  export interface CssAtRuleListener {(context: CssListenerContext, rule:CssNode, identifier:string): void}
  export interface CssListenerContext extends AuditListenerContext {
    ast:CssNode,
    offset:{row:number, col:number, index:number}
  }


  // Supporting Types and Interfaces for the base rule listener context
  export interface IssueReporter {
    addIssue(issue: any, context: AuditListenerContext|RuleListenerContext, severity?: SEVERITY):void
  }

  export interface EventListenerValue {
    value:string,
    rawval:string
  }


  // node types ---------------------------------------------------------------------------------

  export interface AstNode {
    type:AST_NODE_TYPE,
    start:number,
    end:number,
    name?:string,
    source?:AstNode,
    moduleReference?:AstNode,
    elements?:Array<AstNode>,
    raw?:string,
    value?:string,
    callee?:AstNode,
    optional?:boolean,
    parent?:AstNode,
    expression?:AstNode,
    arguments?:AstNode,
    properties?:Array<AstNode>,
    params?:Array<AstNode>,
    body?:Array<AstNode>,
    async?:boolean,
    generator?:boolean,
    id?:string,
    object?:AstNode
  }

  export interface DomNode {
    attribs:DomNodeAttribs,
    children?:Array<DomNode>,
    startIndex:number,
    endIndex:number,
    name?:string,
    type:DOM_NODE_TYPE,
    next?:DomNode,
    prev?:DomNode,
    parent?:DomNode,
    data?:string
  }

  export interface DomNodeAttribs {
    [attribute:string]:string
  }

  export interface CssNode {
    type:CSS_NODE_TYPE,
    name?:string,
    children?:Array<CssNode>,
    loc:CssLoc
    block?:CssNode,
    prelude?:CssNode
  }

  export interface CssLoc {
    source:string,
    start:CssLocator,
    end:CssLocator
  }

  export interface CssLocator {
    column:number,
    line:number,
    offset:number
  }

  export interface JsonNode {
    name:string,
    members: Array<JsonNode>,
    pos:JsonNodePos,
    rawValue?:string,
    type?:JSON_NODE_TYPE,
    value:JsonNode|string|number|boolean
  }

  export interface JsonNodePos {
    row: number,
    col: number,
    start: number,
    end: number,
    index:number     // deprecated 4.2.2
  }

  export interface AttribPos {
    row: number,
    col: number,
    start: number,
    end: number
  }

  export interface LineColPos {
    row: number,
    col: number
  }


  // Supplementary Data
  export interface SuppData {
    obj: object,
    ast: any,
    line: number
    col: number,
    startIndex: number,
    endIndex: number,
    msg?: string,
    position?: number
  }


  // Interfaces for utility classes available to audit authors -----------------------------------

  export interface ContextUtils {
    utils: Utils,
    fsUtils: FsUtils,
    semVerUtils: SemVerUtils,
    DomUtils: DomUtils,
    metaLib: MetaLib,
    AstUtils: AstUtils,
    msgLib: MsgLib,
    cssUtils?: CssUtils,
  }


  /**
   * General helper Utils
   */
  export interface Utils {
    hasAnyProps(obj: object): boolean,
    isProperty(obj: object, name: string): boolean,
    getProperty(obj: object, name: string): any,
    getType(varName: any): string,
    isArrayContentsType(array: Array<any>, type: string|Array<string>): boolean,
    decommentJson(data: string): string,
    parseJson(data:string,comments?:boolean):object,   //TODO
    eatWhitespace(str: string, startIndex: number): string,
    getIndexToWhiteSpace(str: string, startIndex: number): number,
    getLineStart(str: string, index: number): number
  }

  export interface FsUtils {
    getFileTypeSync(filePath:string):string,
    getFileExtSync(filePath:string):string,
    isSymLink(filePath:string):boolean,
    pathExistsSync(filePath:string):boolean,
    fileExistsSync(filePath:string, dir?:boolean ):boolean,
    readJsonSync(filePath:string, comments?:boolean , error?:boolean|FsUtilsErrorCallback),
    writeJsonSync(obj:object, filePath:string, opts?:FsUtilsWriteOptions, error?:boolean|FsUtilsErrorCallback),
    readDirSync(filePath:string):Array<FsUtilsFileSetEntry>,
    createFolderSync(filePath:string):boolean,
    deleteFolderSync (filePath:string,deleteTarget?:boolean),
    getUniqueFilenameSync(template:string):string
  }
  export interface FsUtilsErrorCallback {
    (errorMsg:string):void
  }

  export interface FsUtilsWriteOptions {
    spaces?:number|string,
    replacer(key:string, value:any):any
  }

  export interface FsUtilsFileSetEntry {
    name:string,
    isFile:boolean,
    files:Array<FsUtilsFileSetEntry>
  }

  /**
   * Utilities for semantic version number comparisons
   */
  export interface SemVerUtils {
    isValid(semver:string):boolean,
    isValidRange(semver:string):boolean,
    satisfiesRange(semver:string, range:string):string,
    minVersion(range:string):null|string,
    prerelease(semver:string):null|Array<string>,
    eq(semver1:string, semver2:string):boolean,
    lt(semver1:string, semver2:string):boolean,
    lte(semver1:string, semver2:string):boolean,
    gt(semver1:string, semver2:string):boolean,
    gte(semver1:string, semver2:string):boolean,
    major(semver:string):number,
    minor(semver:string):number,
    patch(semver:string):number,
    parse(semver:string):null|SemanticVersion
  }

  //Supporting types and interfaces for SemVerUtils

  export interface SemanticVersion  {
    options:{loose:boolean, includePrerelease:boolean},
    loose:boolean,
    raw:string,
    major:number,
    minor:number,
    patch:number,
    prerelease:Array<string|number>,
    build:Array<string>,
    version:string
  }


  /**
   * Utilities for working with the HTML DOM
   */
  export interface DomUtils {
    extractAttribsFromDataBind(attrValue: string): object,
    extractComponentFromDataBind(attrValue: string): string|null,
    getName(node: DomNode): string,
    getType(node: DomNode): string,
    getChildren(node: DomNode): Array<DomNode>,
    getParent(node: DomNode): DomNode,
    getSiblings(node: DomNode): Array<DomNode>,
    getAttribs(node: DomNode): DomNodeAttribs,
    getAttribValue(node: DomNode, attrName: string): string,
    getAttribPosition(data: string, node: DomNode, attrName: string): AttribPos,
    getAttribValuePosition(data: string, node: DomNode, attrName: string): AttribPos,
    getAttribIndex(data: string, node: DomNode, attrName: string): number,
    hasAttrib(node: DomNode, attrName: string): boolean,
    hasChildren(node: DomNode): boolean,
    hasNext(node: DomNode): boolean,
    getFirst(): DomNode,
    getFirstElement(): DomNode,
    getLast(): DomNode,
    getBody(): DomNode,
    getHead(): DomNode,
    getLinks(): Array<DomNode>,
    getScripts(): Array<DomNode>,
    getLineCol(data: string, index: number): LineColPos,
    getElemsByName(elemName: string): Array<DomNode>,
    getElemById(id: string): DomNode,
    getElems(): Array<DomNode>,

    isExpression(val: string): boolean,
    getExpression(val: string): string|null
  }

  /**
   * Metadata utilities
   */
  export interface MetaLib {
    isWCTag(tag:string):boolean,
    isJetTag(tag:string):boolean,
    isJetCoreTag(tag:string):boolean,
    isComponentTag(tag:string):boolean,
    isTagDeprecated(tag:string):string|null,
    isTagPackPrivate(tag:string):boolean,
    isTagAttrDeprecated(tag:string, attrName:string):string|null,
    isTagAttrWriteback(tag: string, attrName: string):boolean,
    isTagAttr(tag:string, attrName:string):boolean,
    isTagAttrValue(tag:string, attrName:string, value:string):boolean,
    hasTagAttrValues(tag:string, attrName:string):boolean,
    hasTagSlot(tag:string):boolean,
    isTagSlotName(tag:string, slotName:string):boolean,
    isTagSlotValue(tag:string, slotValue:string):boolean,     // DEPRECATED
    isTagEvent(tag:string, eventName:string):boolean,
    isTagSupportedInTheme(tag:string):boolean,
    isAttrSupportedInTheme(tag:string, attrName:string):boolean,
    isTagStyleDeprecated(tag:string, styleName:string):string|null,
    isTagStyle(tag:string):boolean,
    isStyle(styleName:string):boolean,
    isGenStyle(styleName:string):boolean,
    isClassStyle(styleName:string):boolean,
    isJetStylePrefix(styleName:string): boolean,
    hasJetStylePrefixes():boolean,
    getTagsFromStyle(styleName:string):Array<string>|null,
    getClassesFromStyle(styleName:string):Array<string>|null,
    getClassFromTag(tagName:string):string|null,
    getTagFromClass(className:string):string|null,
    getClassFromModule(module:string):string|null,
    getTagPropType(tagName:string, propName:string):string|null,
    getPreferredSlotContent(tag:string, slot:string):Array<string>|null,
    getPreferredSlotContentEx(tag:string, slot:string):Array<string>|null,
    isBindingTag(tagName:string):boolean,
    isClassRenamed(className:string):RenamedInfo|null,
    isClassDeleted(className:string):string|null,
    isClassDeprecated(className:string):string|null,
    isClassMethodDeleted(className:string, methodName:string):string|null,
    isClassMethodDeprecated(className:string, methodName:string):string|null,
    isClassMemberDeleted(className:string, memberName:string):string|null,
    isClassMemberDeprecated(className:string, memberName:string):string|null,
    isClassFinal(className:string):boolean,
    isClassMethodFinal(className:string):boolean,
    getClassMethodScope(className:string, methodName:string):string|null,
    isComponentDeprecated(className:string):string|null,
    isComponentAttrDeprecated(className:string, attrName:string):string|null,
    isComponentMethodDeprecated(className:string, methodName:string):string|null,
    isComponentDeleted(className:string):string|null,
    isComponentMethodDeleted(className:string, methodName:string):string|null,
    isComponentMemberDeleted(className:string, memberName:string):string|null,
    isRuleIgnored(tag:string, ruleName:string):boolean,
    getRenamedClassList():object,  //TODO
    getDeletedMethodList():object, //TODO
    getDeletedMemberList():object, //TODO
    getRevisionInfo():JetRevisionInfo,
    getMetaVers():object, //TODO
    walkDomStackForOJTag(context:AuditListenerContext, excludeBindIf?:boolean):string|null,
    isTagAttrTranslatable(tag:string, attrName:string):boolean,
    getTagAttrType(tag:string, attrName:string):string|null,
    getInterfaces(tag: string):Array<string>|null,
    getImplementers(iface:string):Array<string>|null,
    getSubcomponentType(tag:string):string,

    getTagAttrMetadata(tag:string, attrName:string):object|null,

    getAllCustomMetadata():object,                  //TODO
    getTagMetadata(tag:string):object|null,         //TODO
    getTagPropMetadata(tag:string, attrName:string):object|null,  //TODO
    getOjcMetadataByPath(path:string):object|null,  //TODO

    getAllPackMetadata():object,                   //TODO
    getPackMetadata(path:string):object|null,      //TODO
    getPackPaths():object,                         //TODO

    getAllResourceMetadata():object,               //TODO
    getResourceMetadata(path:string):object|null,  //TODO
    getResourcePaths():object                      //TODO
  }

  export interface RenamedInfo {
    to:string,
    since:string
  }

  export interface JetRevisionInfo {
    jetVersion:string,
    revision:string,
    tag:string
  }

  /**
   * Utilities for working with the Abstract Syntax Tree
   */
  export interface AstUtils {
    getBlock(node:AstNode):AstNode,
    getBody(node:AstNode):Array<AstNode>,
    getProgram():AstNode,
    isFuncArg(node:AstNode, varName:string):boolean,
    isCommonDocApi(methodName:string):boolean,
    parseDefine(node:AstNode):null|FlattenedDefine,
    getNodeTypes():AstNodeTypeExports
  }

  //Supporting types and interfaces for AstUtils
  export interface FlattenedDefine {
    [parameterName:string]:string
  }
  export interface AstNodeTypeExports {
    ARRAY_EXPR              : string,
    ARROW_FUNC_EXPR         : string,
    ASSIGN_PATTERN          : string,
    ASSIGN_EXPR             : string,
    ASSIGNMENT_EXPR         : string,
    AWAIT_EXPR              : string,
    BINARY_EXPR             : string,
    BLOCK_STMT              : string,
    BREAK_STMT              : string,
    CALL_EXPR               : string,
    CATCH_CLAUSE            : string,
    CLASS_BODY              : string,
    CLASS_DECLARATION       : string,
    CLASS_EXPR              : string,
    CLASS_PROP              : string,
    CONDITIONAL_EXPR        : string,
    CONTINUE_STMT           : string,
    DO_WHILE_STMT           : string,
    DEBUG_STMT              : string,
    EMPTY_STMT              : string,
    EX_REST_PROP            : string,
    EX_SPREAD_STMT          : string,
    EXPR_STMT               : string,
    FOR_STMT                : string,
    FOR_IN_STMT             : string,
    FOR_OF_STMT             : string,
    FUNC_DECLARATION        : string,
    FUNC_EXPR               : string,
    IDENTIFIER              : string,
    IF_STMT                 : string,
    LOGIC_EXPR              : string,
    LABELED_STMT            : string,
    LITERAL                 : string,
    MEMBER_EXPR             : string,
    META_PROP               : string,
    METH_DEF                : string,
    NEW_EXPR                : string,
    OBJ_EXPR                : string,
    OBJ_PATTERN             : string,
    PROGRAM                 : string,
    PROPERTY                : string,
    PROPERTY_DEF            : string,
    REST_ELEM               : string,
    RETURN_STMT             : string,
    SEQUENCE_EXPR           : string,
    SPREAD_ELEM             : string,
    SUPER                   : string,
    SWITCH_CASE             : string,
    SWITCH_STMT             : string,
    TAGGED_TEMPLATE_EXPR    : string,
    TEMPLATE_ELEM           : string,
    TEMPLATE_LIT            : string,
    THIS_EXPR               : string,
    THROW_EXPR              : string,
    TRY_STMT                : string,
    UNARY_EXPR              : string,
    UPDATE_EXPR             : string,
    VAR_DECLARATION         : string,
    VAR_DECLARATOR          : string,
    WHILE_STMT              : string,
    WITH_STMT               : string,
    YIELD_EXPR              : string,
    JSX_ID                  : string,
    JSX_NS_NAME             : string,
    JSX_EMPTY_EXPR          : string,
    JSX_EXPR_CONTAINER      : string,
    JSX_ELEM                : string,
    JSX_CLOSING_ELEM        : string,
    JSX_OPENING_ELEM        : string,
    JSX_ATTRIB              : string,
    JSX_SPREAD_ATTRIB       : string,
    JSX_TEXT                : string,
    EXPORT_DEFAULT_DECL     : string,
    EXPORT_NAMED_DECL       : string,
    EXPORT_ALL_DECL         : string,
    EXPORT_ASSIGNMENT       : string,
    EXPORT_SPECIFIER        : string,
    IMPORT_DECL             : string,
    IMPORT_EQUALS_DECL      : string,
    IMPORT_SPECIFIER        : string,
    IMPORT_DEF_SPECIFIER    : string,
    IMPORT_NS_SPECIFIER     : string,
    ANY_KEYWORD             : string,
    ARRAY_TYPE              : string,
    AS_EXPR                 : string,
    BOOLEAN_KEYWORD         : string,
    EXTERN_MOD_REF          : string,
    FUNCTION_TYPE           : string,
    INTERFACE_BODY          : string,
    INTERFACE_DECL          : string,
    INTERSECTION_TYPE       : string,
    LITERAL_TYPE            : string,
    NUMBER_KEYWORD          : string,
    OBJECT_KEYWORD          : string,
    OPTIONAL_TYPE           : string,
    PROPERTY_SIGNATURE      : string,
    STRING_KEYWORD          : string,
    TUPLE_TYPE              : string,
    TYPE_ALIAS_DECL         : string,
    TYPE_LITERAL            : string,
    TYPE_REF                : string,
    UNION_TYPE              : string
  }

  /**
   * Utilities for working with CSS
   */
  export interface CssUtils {
    isColorName(name:string):boolean,
    isMarkerStyle(style:string):boolean
    getPosition():object //TODO
  }


  /**
   * msgLib utilities
   */
   export interface MsgLib {
     msg(text:string),
     info(text:string, type?:string, force?:boolean),
     error(text:string, prefix?:string),
     warn(text:string),
     debug(text:string),
     assert(text:string)
   }


  //Enums defined as const so that they are transpiled away and don't create extra classes
  export const enum SEVERITY {
    BLOCKER = "blocker",
    CRITICAL = "critical",
    MAJOR = "major",
    MINOR = "minor",
    INFO = "info"
  }

  // Pluuggable API Interfaces ------------------------------------------

  // Passed to JAF init()/initSync()
  export interface AuditPluginProvider {
    name: string;
    version:string;
    description?: string;
    init(pluginContext):any;
    getCapability(string):any;
    getCapabilities():Array<string>;
  }


  // Passed to the AuditPluginProvider init() method
  export interface PluginContext {
    msg(string):void;
    info(string):void;
    debug(string):void;
    error(string):void;
    assert(string):void;
    isDebug:boolean;
    isVerbose:boolean;
    runMode:'cli'|'amd'|'api'|'ojet'
  }


  // Accessable via registation/rule cotext.utils.pluginLib
  export interface PluginLib {
    hasPlugin(pluginName:string):boolean;
    getPlugin(pluginName:string):any|null;
    getPluginCapability(pluginName:string, capability:string):any|null;
    getPluginCapabilities(pluginName:string):Array<string>|null;
    getPluginDescription():string|null;
    getPluginVersion(pluginName:string):string|null;
  }



  export const enum DOM_NODE_TYPE {
    webcomp                     = "webcomp",
    elem                        = "elem",
    globtag                     = "globtag",
    tag                         = "tag",
    ojtag                       = "ojtag",
    script                      = "script",
    link                        = "link",
    attr                        = "attr",
    attrexpr                    = "attrexpr",
    class                       = "class",
    style                       = "style",
    type                        = "type",
    event                       = "event",
    comment                     = "comment",
    doctype                     = "doctype",
    procstmt                    = "procstmt",
    directive                   = "directive",
    json                        = "json",
    compjson                    = "compjson",
    text                        = "text",
    root                        = "root"
  }

  export const enum AST_NODE_TYPE {
    AssignmentExpression        = "AssignmentExpression",
    AssignmentPattern           = "AssignmentPattern",
    ArrayExpression             = "ArrayExpression",
    ArrayPattern                = "ArrayPattern",
    ArrowFunctionExpression     = "ArrowFunctionExpression",
    AwaitExpression             = "AwaitExpression",
    BlockStatement              = "BlockStatement",
    BinaryExpression            = "BinaryExpression",
    BreakStatement              = "BreakStatement",
    CallExpression              = "CallExpression",
    CatchClause                 = "CatchClause",
    ClassBody                   = "ClassBody",
    ClassDeclaration            = "ClassDeclaration",
    ClassExpression             = "ClassExpression",
    ConditionalExpression       = "ConditionalExpression",
    ContinueStatement           = "ContinueStatement",
    DoWhileStatement            = "DoWhileStatement",
    DebuggerStatement           = "DebuggerStatement",
    EmptyStatement              = "EmptyStatement",
    ExperimentalRestProperty    = "ExperimentalRestProperty",
    ExperimentalSpreadProperty  = "ExperimentalSpreadProperty",
    ExpressionStatement         = "ExpressionStatement",
    ForStatement                = "ForStatement",
    ForInStatement              = "ForInStatement",
    ForOfStatement              = "ForOfStatement",
    FunctionDeclaration         = "FunctionDeclaration",
    FunctionExpression          = "FunctionExpression",
    Identifier                  = "Identifier",
    IfStatement                 = "IfStatement",
    Literal                     = "Literal",
    LabeledStatement            = "LabeledStatement",
    LogicalExpression           = "LogicalExpression",
    MemberExpression            = "MemberExpression",
    MetaProperty                = "MetaProperty",
    MethodDefinition            = "MethodDefinition",
    NewExpression               = "NewExpression",
    ObjectExpression            = "ObjectExpression",
    ObjectPattern               = "ObjectPattern",
    Program                     = "Program",
    Property                    = "Property",
    RestElement                 = "RestElement",
    ReturnStatement             = "ReturnStatement",
    SequenceExpression          = "SequenceExpression",
    SpreadElement               = "SpreadElement",
    Super                       = "Super",
    SwitchCase                  = "SwitchCase",
    SwitchStatement             = "SwitchStatement",
    TaggedTemplateExpression    = "TaggedTemplateExpression",
    TemplateElement             = "TemplateElement",
    TemplateLiteral             = "TemplateLiteral",
    ThisExpression              = "ThisExpression",
    ThrowStatement              = "ThrowStatement",
    TryStatement                = "TryStatement",
    UnaryExpression             = "UnaryExpression",
    UpdateExpression            = "UpdateExpression",
    VariableDeclaration         = "VariableDeclaration",
    VariableDeclarator          = "VariableDeclarator",
    WhileStatement              = "WhileStatement",
    WithStatement               = "WithStatement",
    YieldExpression             = "YieldExpression",
    JSXIdentifier               = "JSXIdentifier",
    JSXNamespacedName           = "JSXNamespacedName",
    JSXMemberExpression         = "JSXMemberExpression",
    JSXEmptyExpression          = "JSXEmptyExpression",
    JSXExpressionContainer      = "JSXExpressionContainer",
    JSXElement                  = "JSXElement",
    JSXClosingElement           = "JSXClosingElement",
    JSXOpeningElement           = "JSXOpeningElement",
    JSXAttribute                = "JSXAttribute",
    JSXSpreadAttribute          = "JSXSpreadAttribute",
    JSXText                     = "JSXText",
    ExportDefaultDeclaration    = "ExportDefaultDeclaration",
    ExportNamedDeclaration      = "ExportNamedDeclaration",
    ExportAllDeclaration        = "ExportAllDeclaration",
    ExportSpecifier             = "ExportSpecifier",
    ImportDeclaration           = "ImportDeclaration",
    ImportSpecifier             = "ImportSpecifier",
    ImportDefaultSpecifier      = "ImportDefaultSpecifier",
    ImportNamespaceSpecifier    = "ImportNamespaceSpecifier",
    TSImportEqualsDeclaration   = "TSImportEqualsDeclaration"
  }

  export const enum CSS_NODE_TYPE {
    Declaration                 = "Declaration",
    StyleSheet                  = 'StyleSheet',
    Selector                    = "Selector",
    SelectorList                = "SelectorList",
    TypeSelector                = "TypeSelector",
    PseudoClassSelector         = "PseudoClassSelector",
    AttributeSelector           = "AttributeSelector",
    Identifier                  = "Identifier",
    Function                    = "Function",
    String                      = "String",
    HexColor                    = "HexColor",
    Rule                        = "Rule",
    Block                       = "Block",
    Value                       = "Value"
  }

  export const enum JSON_NODE_TYPE {
    Object                      = "Object",
    string                      = "string",
    number                      = "number",
    boolean                     = "boolean"
  }
}

declare module 'ojaf' {
  export default ojaf;
}