import IFeature from "./IFeature"
import { Container } from "../container/Container"
import ClassName, { GetClassName } from "../container/ClassName"
import Atk from "../feature/Atk"
import { Injectable } from "../container/Injectable"
import Logger from "../class/Logger"
import BuyBeerHelper from "../feature/BuyBeerHelper"
import SidebarHelper from "../feature/SidebarHelper"
import TravelItem from "../feature/TravelItem"
import TravelHelper from "../feature/TravelHelper"
import CompanyHelper from "../feature/CompanyHelper"
import IconHelper from "../feature/IconHelper"
import MapItem from "../feature/MapItem"
import PTHelper from "../class/action/PTHelper"
import StackHelper from "../feature/StackHelper"
import XZMZ from "../class/action/XZMZ"
import BeerShopModifier from "../feature/BeerShopModifier"
import CrimePageModifier from "../feature/CrimePageModifier"
import ProfileHelper from "../class/action/ProfileHelper"
import ChristmasTown from "../feature/ChristmasTown"
import LotteryHelper from "../feature/LotteryHelper"
import SlotsHelper from "../class/action/SlotsHelper"
import SearchHelper from "../class/action/SearchHelper"
import { WHIntervalLoader } from "../monitor/WHIntervalLoader"
import IFeatureResult from "./IFeatureResult"
import FeatureStatus from "./const/FeatureStatus"
import globVars from "../globVars";

@ClassName('FeatureMan')
@Injectable()
export default class FeatureMan {
    private readonly features: ClassType<IFeature>[] = [
        /* 通配 */
        BuyBeerHelper,
        SidebarHelper,
        TravelItem,
        CompanyHelper,
        IconHelper,
        WHIntervalLoader,
        /* 页面匹配 */
        Atk,
        TravelHelper,
        MapItem,
        PTHelper,
        StackHelper,
        XZMZ,
        BeerShopModifier,
        CrimePageModifier,
        ProfileHelper,
        ChristmasTown,
        LotteryHelper,
        SlotsHelper,
        SearchHelper,
    ]
    private result: IFeatureResult[] = null
    private readonly logger = Logger.factory(FeatureMan)

    async fStart() {
        const manResult: IFeatureResult[] = []
        for (let i = 0; i < this.features.length; i++) {
            const className = GetClassName(this.features[i])
            const instant = Container.factory(this.features[i])
            const description = instant.description()
            const urlPath = location.href.replace(/^.+\/\/.+?\/(?!\/)?/, '/')
            let status = FeatureStatus.ADDED
            let isMatch = false
            const urlIncludes = instant.urlIncludes()
            let load = 0
            for (let j = 0; j < urlIncludes.length; j++) {
                if (urlIncludes[j].test(urlPath)) {
                    isMatch = true
                    const urlExcludes = instant.urlExcludes() ?? []
                    for (let k = 0; k < urlExcludes.length; k++) {
                        if (urlExcludes[k].test(urlPath)) {
                            isMatch = false
                            status = FeatureStatus.EXCLUDED
                            break
                        }
                    }
                    break
                }
            }
            if (isMatch) {
                try {
                    const start = performance.now()
                    let run = instant.iStart()
                    if (run instanceof Promise) {
                        run = await run
                    }
                    status = FeatureStatus.RUNNING
                    load = ((performance.now() - start) * 10 | 0) / 10
                } catch (e) {
                    this.logger.error(e.message)
                    status = FeatureStatus.EXCEPTION
                }
            }
            // else {
            //     status = FeatureStatus.EXCLUDED
            // }
            const result = {
                desc: description,
                status: status,
                clazz: className,
                load
            }
            manResult.push(result)
            globVars.featureStatus.push(result)
        }
        this.result = manResult
    }

    printTable() {
        console.table(this.result)
        this.logger.info(this.result)
    }
}
