import { nanoid } from '../nanoid.js'
import { Certificate, ICertificate } from './ClientCertificate.js'
import { CertificateFileKind } from './kinds.js'
import { IFile, File } from './store/File.js'
import { Thing } from './Thing.js'

export interface ICertificateFile extends IFile {
  kind: typeof CertificateFileKind
}

export class CertificateFile extends File {
  override kind = CertificateFileKind

  static fromCertificate(certificate: ICertificate | Certificate): CertificateFile {
    const init: ICertificateFile = {
      kind: CertificateFileKind,
      key: certificate.key,
      info: Thing.fromName(certificate.name).toJSON(),
      lastModified: { user: '', time: 0, byMe: false },
      parents: [],
      permissionIds: [],
      permissions: [],
    }
    return new CertificateFile(init)
  }

  /**
   * @param name The name to set.
   */
  static override fromName(name: string): CertificateFile {
    return super.fromName(name, CertificateFileKind) as CertificateFile
  }

  constructor(input?: string | ICertificateFile) {
    super()
    let init: ICertificateFile
    if (typeof input === 'string') {
      init = JSON.parse(input)
    } else if (typeof input === 'object') {
      init = input
    } else {
      init = {
        kind: CertificateFileKind,
        key: nanoid(),
        info: Thing.fromName('').toJSON(),
        parents: [],
        permissionIds: [],
        permissions: [],
        lastModified: { user: '', time: 0, byMe: false },
      }
    }
    this.new(init)
  }

  override new(init: ICertificateFile): this {
    if (!CertificateFile.isCertificate(init)) {
      throw new Error(`Not a certificate file.`)
    }
    super.new(init)
    this.kind = CertificateFileKind
    return this
  }

  static isCertificate(input: unknown): boolean {
    const typed = input as ICertificateFile
    if (!input || typed.kind !== CertificateFileKind) {
      return false
    }
    return true
  }

  override toJSON(): ICertificateFile {
    const result: ICertificateFile = {
      ...super.toJSON(),
      kind: CertificateFileKind,
    }
    return result
  }
}
