
// import { promises as fs } from 'fs'
// import MarkdownIt from 'markdown-it'
// import slugify from 'slugify'

// import statuses from './statuses'
// import parseDate from './parse-github-date'

const marked = require('marked')
const HTMLParser = require(`node-html-parser`)

import { getAppEndpoint } from './app-derived'
import { getJson } from './http.js'


const statusesTranslations = {

    // brew install -s succeeds on Apple Silicon. The software works well enough natively.
    '🥇': 'native',

    // The formula has been updated with depends_on :arch => [:x86_64, :build]. The software works well enough on Rosetta.
    '🥈': 'rosetta',

    // The formula has known issues on macOS 11, though most features work. The issues are described in the Comments field.
    '🥉': 'rosetta',

    // The formula has been updated with depends_on :arch => :x86_64. The software has been deemed to work on Intel only (for now).
    '🚫': 'no',

    // The formula has been found to need more analysis/work.
    '⚠️': 'no',

    '': 'unreported'
}

const statusesMessages = {
    '🥇': '✅ Yes, Native Apple Silicon Support',
    '🥈': '✳️ Yes, works via Rosetta 2',
    '🥉': '⏹ Known issues on macOS 11, though most features work',
    '⚠️': '⏹ No, not yet, support is still in progress',
    '🚫': '🚫 No, not yet supported only works on Intel-based Macs',
    '': '🔶 Unknown, more info needed'
}


class MakeHomebrewList {

    constructor() {
        // Data from the issue
        this.issueTableRowData = null

        // Data from the official Homebrew API
        this.allFormulaeArray = null
        this.allFormulae = null
    }

    getStatusText ( formula ) {
        // Match status to Sheet Status
        return statusesMessages[formula.status]
    }

    searchFormulaeForName (name) {
        for (const formula of this.allFormulaeArray) {
            // Check normal name
            if (formula.name === name) return formula

            // Check normal oldname
            if (formula.oldname === name) return formula

            // Check aliases
            if ((formula.aliases !== undefined) && formula.aliases.includes(name)) return formula

        }

        return null
    }

    hasArm64Formula( formulaData ) {
        // Check the official list first since it's data is newer and more frequently updated
        const hasStableFormula = (formulaData.bottle.stable !== undefined)

        return hasStableFormula && (formulaData.bottle.stable.files['arm64_big_sur'] !== undefined)
    }

    formulaIsNative (formulae) {
        // Search Formulae from Homebrew API
        const formulaData = this.allFormulae[formulae.fullName] || this.searchFormulaeForName(formulae.name)

        // console.log('formulae.fullName', formulae.fullName)

        // If this formula doesn't exist
        // then return false
        if (formulaData !== Object(formulaData)) {
            return false
        }

        // console.log('formulaData', formulaData)
        // console.log('formulae', formulae)

        // Check the official list first since it's data is newer and more frequently updated
        const hasStableFormula = (formulaData.bottle.stable !== undefined)
        const hasArm64Formula = hasStableFormula && (formulaData.bottle.stable.files['arm64_big_sur'] !== undefined)

        return this.hasArm64Formula( formulaData )
    }

    parseStatus (formulae) {
        // Match status to Sheet Status
        return statusesTranslations[formulae.status]
    }

    async make () {

        // Fetch Gihub Issue List
        const [
            issueResponse,
            allFormulaeResponse
        ] = await Promise.all([
            // Fetch Gihub Issue List
            getJson( process.env.HOMEBREW_SOURCE ),
            // Fetch Official Homebrew Formulae List
            getJson( 'https://formulae.brew.sh/api/formula.json' )
        ])

        // Extract commit from response data
        const issueMarkdown = issueResponse.data.repository.issue.body

        // Parse markdown
        const issueHTML = marked(issueMarkdown)

        // Parse Markdown HTML into a dom
        const dom = HTMLParser.parse(issueHTML)

        // Store the original array
        this.allFormulaeArray = allFormulaeResponse

        // Extract list from allFormulaeResponse and map into an object for easy access
        this.allFormulae = Object.fromEntries(allFormulaeResponse.map(formula => {
            return [
                formula.full_name,
                formula
            ]
        }))



        // console.log('allFormulae', allFormulae)


        // Map table Headings
        // [ 'Formula', 'Works1on 11.0', 'Comments' ]
        // const tableHeadings = dom.querySelectorAll('thead th').map(th => th.rawText)

        const headings = [
            'fullName',
            'status',
            'comments'
        ]

        // Map Formulae List within table
        const tableRows = dom.querySelectorAll('table tr')

        // Remove the first row (Headings)
        tableRows.shift()

        this.issueTableRowData = tableRows.map( tr => {

            // Map Table Cells

            const cellsData = tr.querySelectorAll('td').map((td, i) => {

                const column = headings[i]

                if (td.childNodes.length === 0) return ''

                if (column === 'comments') return td.innerHTML

                return td.rawText
            })

            const formulaeRow = Object.fromEntries(cellsData.map( (cellData, i) => {
                return [ headings[i], cellData ]
            }))

            formulaeRow.name = formulaeRow.fullName.split(' ')[0]

            formulaeRow.links = []
            // formulaeRow.links = tr.querySelectorAll('a').map( a => {
            //     const href = a.getAttribute('href')
            //     return {
            //         href,
            //         label: a.rawText,
            //         // a
            //     }
            // })

            // if (formulaeRow.links.length !== 0) console.log('formulaeRow', formulaeRow.links)

            const isNativeInApi = this.formulaIsNative(formulaeRow)

            if (isNativeInApi) {
                // Update status
                formulaeRow.status = '🥇'
            }

            return formulaeRow
        })

        // console.log('dom', dom.length)
        // console.log('issueHTML', issueHTML)
        // console.log('formulaeWithStatus', formulaeWithStatus)


        const formulaeList = new Map()

        const category = {
            slug: 'homebrew'
        }

        // for (const formula of Object.values( this.allFormulae )) {

        //     const isNative = this.hasArm64Formula( formula )
        //     const status = isNative ? 'native' : 'unreported'
        //     const statusText = isNative ? '✅ Yes, Native Apple Silicon Support' : '🔶 Formula has not yet been reported to be native to Apple Silicon'
        //     const slug = formula.full_name

        //     formulaeList.set(formula.full_name, {
        //         name: formula.full_name,
        //         status: status,
        //         // url: `https://formulae.brew.sh/formula/${formulae.name}`,
        //         text: statusText,
        //         slug,
        //         endpoint: getAppEndpoint({
        //             slug,
        //             category
        //         }),//`/formula/${slug}`,
        //         category,
        //         content: null,npm
        //         relatedLinks: [
        //             {
        //                 href: `https://formulae.brew.sh/formula/${formula.name}`,
        //                 label: formula.full_name,
        //                 // a
        //             },
        //             // ...formula.links
        //         ],
        //         // reports: [
        //         //     formulae
        //         // ]
        //     })

        // }


        for (const formulae of this.issueTableRowData) {

            // If this formulae status is empty
            // then skip this formulae
            // if (formulae.status.length === 0) continue

            // If this formulae emoji status is not in statusesTranslations
            // then skip this formulae
            if (!statusesTranslations.hasOwnProperty(formulae.status)) continue

            // Generate slug
            const slug = formulae.name

            // slugify(formulae.name, {
            //     lower: true,
            //     strict: true
            // })

            formulaeList.set(formulae.name, {
                name: formulae.name,
                status: this.parseStatus(formulae),
                // url: `https://formulae.brew.sh/formula/${formulae.name}`,
                text: this.getStatusText(formulae),
                slug,
                endpoint: getAppEndpoint({
                    slug,
                    category
                }),//`/formula/${slug}`,
                category,
                content: '',//formulae.comments,
                relatedLinks: [
                    {
                        href: `https://formulae.brew.sh/formula/${formulae.name}`,
                        label: formulae.name,
                        // a
                    },
                    ...formulae.links
                ],
                // reports: [
                //     formulae
                // ]
            })
        }

        // console.log('formulaeList', formulaeList)

        return Array.from( formulaeList , ([_, data]) =>  data )
    }
}


export default async function () {
    const maker = new MakeHomebrewList()

    return await maker.make()
}
