{-# LANGUAGE OverloadedStrings #-}
module Media.TS (compileTypeScriptCompiler) where

import           Control.Monad   ((>=>))
import           Hakyll
import           System.FilePath (takeFileName, (</>))
import           System.IO.Temp  (withSystemTempDirectory)
import           System.Process  (callProcess)

-- | TypeScriptファイルをコンパイルするCompiler
-- disney-experience-visualizations.ts の場合はViteバンドラーを使用し、
-- それ以外のファイルは従来のstdin方式でコンパイルする
compileTypeScriptCompiler :: Compiler (Item String)
compileTypeScriptCompiler :: Compiler (Item FilePath)
compileTypeScriptCompiler = do
    -- リソースのファイルパスを取得
    FilePath
filePath <- Compiler FilePath
getResourceFilePath
    let fileName :: FilePath
fileName = FilePath -> FilePath
takeFileName FilePath
filePath

    -- disney-experience-visualizations.ts の場合はViteを使用
    if FilePath
fileName FilePath -> FilePath -> Bool
forall a. Eq a => a -> a -> Bool
== FilePath
"disney-experience-visualizations.ts"
        then Compiler (Item FilePath)
compileWithVite
        else Compiler (Item FilePath)
getResourceString Compiler (Item FilePath)
-> (Item FilePath -> Compiler (Item FilePath))
-> Compiler (Item FilePath)
forall a b. Compiler a -> (a -> Compiler b) -> Compiler b
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= (FilePath -> Compiler FilePath)
-> Item FilePath -> Compiler (Item FilePath)
forall a b. (a -> Compiler b) -> Item a -> Compiler (Item b)
withItemBody FilePath -> Compiler FilePath
compileTS
  where
    -- 従来のstdin方式でのコンパイル
    compileTS :: FilePath -> Compiler FilePath
compileTS = FilePath -> [FilePath] -> FilePath -> Compiler FilePath
unixFilter FilePath
"tools/ts-stdin-compile.sh" []
            (FilePath -> Compiler FilePath)
-> (FilePath -> Compiler FilePath) -> FilePath -> Compiler FilePath
forall (m :: * -> *) a b c.
Monad m =>
(a -> m b) -> (b -> m c) -> a -> m c
>=> FilePath -> [FilePath] -> FilePath -> Compiler FilePath
unixFilter FilePath
"npx" [FilePath
"terser", FilePath
"--compress", FilePath
"--mangle", FilePath
"--format", FilePath
"comments=false", FilePath
"--ecma", FilePath
"6", FilePath
"--"]

-- | Viteを使用してTypeScriptをバンドル・コンパイルする
compileWithVite :: Compiler (Item String)
compileWithVite :: Compiler (Item FilePath)
compileWithVite = do
    FilePath
content <- IO FilePath -> Compiler FilePath
forall a. IO a -> Compiler a
unsafeCompiler (IO FilePath -> Compiler FilePath)
-> IO FilePath -> Compiler FilePath
forall a b. (a -> b) -> a -> b
$ FilePath -> (FilePath -> IO FilePath) -> IO FilePath
forall (m :: * -> *) a.
(MonadIO m, MonadMask m) =>
FilePath -> (FilePath -> m a) -> m a
withSystemTempDirectory FilePath
"vite-build" ((FilePath -> IO FilePath) -> IO FilePath)
-> (FilePath -> IO FilePath) -> IO FilePath
forall a b. (a -> b) -> a -> b
$ \FilePath
tmpDir -> do
        -- Viteでビルド(出力先を一時ディレクトリに指定)
        FilePath -> [FilePath] -> IO ()
callProcess FilePath
"npx" [FilePath
"vite", FilePath
"build", FilePath
"--config", FilePath
"vite.config.production.ts", FilePath
"--outDir", FilePath
tmpDir]

        -- 生成されたJavaScriptファイルを読み込む
        let outputFile :: FilePath
outputFile = FilePath
tmpDir FilePath -> FilePath -> FilePath
</> FilePath
"disney-experience-visualizations.js"
        FilePath -> IO FilePath
readFile FilePath
outputFile

    -- makeItemを使用してHakyllが正しいIdentifierを設定
    FilePath -> Compiler (Item FilePath)
forall a. a -> Compiler (Item a)
makeItem FilePath
content