package app.crossword.yourealwaysbe.forkyz.net

import java.io.InputStream
import java.util.Locale
import java.util.regex.Pattern

import app.crossword.yourealwaysbe.forkyz.util.apacheGetURLInputStream
import app.crossword.yourealwaysbe.puz.Puzzle
import app.crossword.yourealwaysbe.puz.io.SlowDownWiseUpJSONIO

/**
 * Scraper for puzzles embedded in Wall Street Journal
 *
 * Check is Wall Street Journal by looking for wsj.com.
 *
 * Get puzzle data URL by looking for puzzles/crossword/yyyymmdd/xxxxx
 * where xxxxx is a numeric puzzle ID. Data is then
 * wsj.com/puzzles/crossword/yyyymmdd/xxxxx/data.json.
 *
 * Need Apache HttpClient library to get data.json, HttpURLConnection
 * gets rejected.
 */
class WSJStreamScraper : AbstractStreamScraper() {
    @Throws(Exception::class)
    public override fun parseInput(
        inputStream : InputStream,
        url : String?,
    ) : Puzzle? {
        val jsonURL = getJSONURL(inputStream)
        if (jsonURL == null)
            return null

        try {
            apacheGetURLInputStream(jsonURL, timeout).use { jsonIS ->
                val puz = SlowDownWiseUpJSONIO.readPuzzle(jsonIS)
                puz?.source = DEFAULT_SOURCE
                return puz
            }
        } catch (e : Exception) {
            // fall through
        }

        return null
    }

    fun getJSONURL(inputStream : InputStream) : String? {
        val matchers = arrayOf(WSJ_MATCH, PUZZLE_PATH_MATCH)
        val results = regexScrape(inputStream, matchers)
        val isWSJ = results[0]
        val puzzlePath = results[1]

        if (isWSJ == null || puzzlePath == null)
            return null
        else
            return String.format(Locale.US, DATA_URL_FORMAT, puzzlePath)
    }

    companion object {
        private val WSJ_MATCH = RegexScrape(Pattern.compile("wsj.com"), 0)
        private val PUZZLE_PATH_MATCH = RegexScrape(
            Pattern.compile("puzzles/crossword/\\d{8}/\\d+"),
            0,
        )

        private const val DEFAULT_SOURCE = "Wall Street Journal"

        // args: puzzles/crossword/yyyymmdd/xxxxx
        private const val DATA_URL_FORMAT = "https://www.wsj.com/%s/data.json"
    }
}

