import * as ts from "typescript"
import * as pathModule from "path"
import * as fs from "fs-extra"
export class TSConfigParser {
    public sourceFile: ts.SourceFile
    public result: {
        Template?: string
        Output?: string
        StyleOutput?: string
        Root?: string
    } = {}
    constructor(public readonly filePath: string) {
        let content = fs.readFileSync(this.filePath, "utf8")
        console.log(content)
        this.sourceFile = ts.createSourceFile(this.filePath, content, ts.ScriptTarget.ES5, true)
        this.traverseAndParse()
    }
    getTemplatePath(): string {
        let basedir = pathModule.dirname(this.filePath) + "/"
        let templatePath = pathModule.resolve(basedir, this.result.Template || "template")
        return templatePath
    }
    getOutputPath(): string {
        let basedir = pathModule.dirname(this.filePath) + "/"
        let outputPath = pathModule.resolve(basedir, this.result.Output || "R.d.ts")
        return outputPath
    }
    getRootPath(): string {
        let basedir = pathModule.dirname(this.filePath) + "/"
        if (!this.result.Root) return basedir
        let outputPath = pathModule.resolve(basedir, this.result.Root)
        return outputPath
    }
    getStyleOutputPath(): string {
        if (!this.result.StyleOutput) return ""
        let basedir = pathModule.dirname(this.filePath) + "/"
        let styleOutputPath = pathModule.resolve(basedir, this.result.StyleOutput || "R.d.ts")
        return styleOutputPath
    }
    traverseAndParse() {
        ts.forEachChild(this.sourceFile, (child) => {
            if (child.kind === ts.SyntaxKind.TypeAliasDeclaration) {

                let node = child as ts.TypeAliasDeclaration
                let name = node.name as ts.Identifier
                let type = node.type as ts.LiteralTypeNode
                let typeLiteral = type.literal
                let nameString = name.text
                if (typeLiteral.kind !== ts.SyntaxKind.StringLiteral) {
                    throw new Error("Invalid type declaration" + getSyntaxKindName(typeLiteral.kind))
                }
                let stringLiteral = typeLiteral as ts.StringLiteral
                let contentString = stringLiteral.text
                this.result[nameString] = contentString
            } else {
                //console.error("pass", getSyntaxKindName(child.kind))
            }
        })
    }
    getDeclareName(node: ts.Node) {
        let name: string = null
        ts.forEachChild(node, (child) => {
            if (child.kind === ts.SyntaxKind.Identifier) {
                name = (child as ts.Identifier).text
            }
        })
        return name
    }
}



interface KindTree {
    name: string
    children: KindTree[]
}
function getSyntaxKindName(kind) {
    for (let name in ts.SyntaxKind) {
        if (ts.SyntaxKind[name] === kind) {
            return name
        }
    }
    return "Unknown"
}
function getKindTree(node: ts.Node): KindTree {
    let tree: KindTree = {
        name: getSyntaxKindName(node.kind)
        , children: []
    }
    ts.forEachChild(node, (child) => {
        tree.children.push(getKindTree(child))
    })
    return tree
}
function inspectKind(node: ts.Node) {
    let tree = getKindTree(node)
    console.log(JSON.stringify(tree, null, 2))
}
