const CRLF: string = '\n'
const INDENT: string = '\u0020\u0020'
interface generateBase {
  CRLF: string,
  INDENT: string,
  STARTCODE: string,
  ENDCODE: string,
  CODE: string,
  COMPOSE?: Record<string | number | symbol, any>
}
interface visitorInterface {
  before(name: string, props: any): any
  executing(isString: boolean, props: any, key: string): any
  after (code: string): any
}
class GeneraeBase {
  CRLF = CRLF
  INDENT = INDENT
  CODE = ''
  STARTCODE = ''
  ENDCODE = ''
  composeCode(CODE: string) {
    return (this.STARTCODE + this.CRLF + this.INDENT + CODE + this.CRLF + this.ENDCODE + this.CRLF)
  }
  baseGenerate(name: string, props: any, visitor: visitorInterface) {
    let STARTTAG = `<${name}`
    let closeTag = '>'
    props = Object.assign({}, props)
    visitor.before && visitor.before(name, props)
    for (let key in props) {
      if (props.hasOwnProperty(key)) {
        let isString = this.isString(props[key])
        visitor.executing && visitor.executing(isString, props, key)
        STARTTAG += this.CRLF + this.INDENT
        STARTTAG += `${
          isString ? '' : ':'
          }${key}='${isString ? props[key] : key}'`
      }
    }
    STARTTAG += closeTag
    STARTTAG += this.CRLF + this.INDENT
    STARTTAG = (visitor.after && visitor.after(STARTTAG)) || STARTTAG
    STARTTAG += `</${name}>`
    return STARTTAG
  }
  isString(val: any): boolean {
    return typeof val === 'string'
  }
}
//基础模板类
class GenerateTpl extends GeneraeBase implements generateBase {
  STARTCODE = `<template>`
  ENDCODE = `</template>`
  COMPOSE = {}
}
//基础脚本类
class GenerateJs extends GeneraeBase implements generateBase {
  STARTCODE: string = `<script>`
  ENDCODE: string = `</script>`
}
//基础样式类
class GenerateStyle extends GeneraeBase implements generateBase {
  STARTCODE: string = `<style>`
  ENDCODE: string = `</style>`
}

export { GenerateTpl, GenerateJs, GenerateStyle }
