import { DefineSchema, RegisterSchema } from 'koishi-thirdeye';
import ip from 'ip';
import Tesseract, { createWorker } from 'tesseract.js';
import { Logger } from 'koishi';
import path from 'path';

@RegisterSchema()
export class HisoutensokuJammerPluginConfig {
  constructor(config: Partial<HisoutensokuJammerPluginConfig>) {}
  @DefineSchema({ description: '干扰时间', default: 10000, role: 'ms' })
  attackTimeout: number;

  @DefineSchema({ description: 'IP 白名单', default: [], type: 'string' })
  addressWhitelist: string[];

  @DefineSchema({ description: '开启文字识别', default: false })
  ocr: boolean;

  @DefineSchema({ description: '模型语言', default: 'eng' })
  ocrLanguage: string;

  @DefineSchema({ type: 'object' })
  ocrExtraOptions: Partial<Tesseract.WorkerOptions>;

  @DefineSchema({ type: 'object' })
  ocrExtraParameters: Partial<Tesseract.WorkerParams>;

  async loadOcr() {
    if (!this.ocr) return;
    const logger = new Logger('jammer-ocr');
    if (this.ocrExtraOptions?.dataPath) {
      logger.info(
        `Will load esseract.js data files from ${this.ocrExtraOptions?.dataPath}`,
      );
    }
    try {
      const worker = createWorker({
        logger: (m) => logger.info(m),
        //dataPath: path.join(__dirname, '..', 'lang-data'),
        ...(this.ocrExtraOptions || {}),
      });
      await worker.load();
      await worker.loadLanguage(this.ocrLanguage);
      await worker.initialize(this.ocrLanguage);
      await worker.setParameters({
        tessedit_char_whitelist: '0123456789.: _-+',
        ...(this.ocrExtraParameters || {}),
      });
      logger.info(`OCR worker loaded.`);
      return worker;
    } catch (e) {
      logger.error(`Failed to load OCR worker: ${e.toString()}`);
      return;
    }
  }

  getSubnet(addr: string) {
    return ip.cidrSubnet(addr.includes('/') ? addr : `${addr}/32`);
  }

  isWhitelisted(addr: string) {
    return this.addressWhitelist.some((whitelistAddr) =>
      this.getSubnet(whitelistAddr).contains(addr),
    );
  }
}

export type HisoutensokuJammerPluginConfigLike =
  Partial<HisoutensokuJammerPluginConfig>;
