-- vim:set ft=lua:
-- メタ情報の取得、mp4などのトランスコードしないファイルを転送するスクリプト

dofile(mg.script_name:gsub('[^\\/]*$','')..'util.lua')

-- コマンドはEDCBのToolsフォルダにあるものを優先する
tools=EdcbModulePath()..'\\Tools\\'
ffprobe=(edcb.FindFile(tools..'\\ffprobe.exe',1) and tools..'\\' or '')..'ffprobe.exe'
tsreadex=(edcb.FindFile(tools..'\\tsreadex.exe',1) and tools..'\\' or '')..'tsreadex.exe'

query=mg.request_info.query_string
fpath=GetFilePath(query)

f=nil
if fpath then
  fname='xcode'..(fpath:match('%.[0-9A-Za-z]+$') or '')
  f=edcb.io.open(fpath, 'rb')
  if f then
    if mg.get_var(query,'meta') then
      fsec,fsize=GetDurationSec(f)
      ff=edcb.FindFile and edcb.FindFile(ffprobe, 1)
      meta={duration=fsec, audio={}}
      if ff then
        offset=math.floor(fsize*10/100/188)*188
        local fp=edcb.io.popen('""'..tsreadex..'" -s '..offset..' "'..fpath..'" | "'
          ..ffprobe..'" -i pipe:0 -hide_banner 2>&1"', 'rb')
        if fp then
          for v in (fp:read('*a') or ''):gmatch(':%sAudio:%s(.-)\r\n') do
            table.insert(meta.audio,v)
          end
          fp:close()
        end
      end
      f:close()
    else
      offset=tonumber(mg.get_var(query,'offset')) or 0
      if offset~=0 then
        fsec,fsize=GetDurationSec(f)
        if offset~=100 and SeekSec(f,fsec*offset/100,fsec,fsize) then
          offset=f:seek('cur',0) or 0
        else
          offset=math.floor(fsize*offset/100/188)*188
        end
      end
      f:seek('set', offset)
    end
  end
end

if meta then
  ct='<?xml version="1.0" encoding="UTF-8" ?><entry>'..(meta.duration~=0 and '<duration>'..meta.duration..'</duration>' or '')..'<audio>'..#meta.audio..'</audio></entry>'
  mg.write(Response(200,'text/xml', 'utf-8', #ct) ..'\r\n'..(mg.request_info.request_method~='HEAD' and ct or ''))
elseif not f then
  mg.write(Response(404,'text/html','utf-8')..'\r\n')
else
  mg.write(Response(200,mg.get_mime_type(fname))..'Content-Disposition: filename='..fname..'\r\n\r\n')
  if mg.request_info.request_method~='HEAD' then
    retry=0
    while true do
      buf=f:read(48128)
      if buf and #buf ~= 0 then
        retry=0
        if not mg.write(buf) then
          -- キャンセルされた
          mg.cry('canceled')
          break
        end
      else
        -- 終端に達した。4秒間この状態が続けば対象ファイルへの追記が終息したとみなす
        retry=retry+1
        if retry > 20 then
          mg.cry('end')
          break
        end
        edcb.Sleep(200)
      end
    end
  end
  f:close()
end
