/* @flow */

import Rule from '../Rule'

import type { Action, Command, ParsedLog } from '../types'

const MESSAGE_PATTERN = /^\s+--\s*(.*)$/

export default class ParseMakeIndexLog extends Rule {
  static parameterTypes: Array<Set<string>> = [new Set(['MakeIndexLog'])]
  static commands: Set<Command> = new Set(['build', 'log'])
  static defaultActions: Array<Action> = ['parse']
  static description: string = 'Parses any logs generated by makeindex.'

  async parse () {
    const output = await this.getResolvedOutput('$DIR_0/$BASE_0-ParsedMakeIndexLog')
    if (!output) return false

    const parsedLog: ParsedLog = {
      messages: [],
      inputs: [],
      outputs: [],
      calls: []
    }

    await this.firstParameter.parse([{
      names: ['input'],
      patterns: [
        /^Scanning (?:style|input) file (.*?)[.]+done .*$/
      ],
      evaluate: (reference, groups) => {
        parsedLog.inputs.push(this.normalizePath(groups.input))
      }
    }, {
      names: ['output'],
      patterns: [
        /^(?:Output|Transcript) written in (.*?)\.*$/
      ],
      evaluate: (reference, groups) => {
        parsedLog.outputs.push(this.normalizePath(groups.output))
      }
    }, {
      names: ['inputPath', 'inputLine', 'outputPath', 'outputLine', 'text'],
      patterns: [
        /## Warning \(input = (.+), line = (\d+); output = (.+), line = (\d+)\):/,
        MESSAGE_PATTERN
      ],
      evaluate: (reference, groups) => {
        const line = parseInt(groups.inputLine, 10)
        parsedLog.messages.push({
          severity: 'warning',
          name: 'makeindex',
          text: groups.text,
          log: reference,
          source: {
            file: groups.inputPath,
            range: {
              start: line,
              end: line
            }
          }
        })
      }
    }, {
      names: ['category', 'file', 'line', 'text'],
      patterns: [
        /^[*!]+ (Input (?:index|style)) error \(file = (.+), line = (\d+)\):$/,
        MESSAGE_PATTERN
      ],
      evaluate: (reference, groups) => {
        const line = parseInt(groups.line, 10)
        parsedLog.messages.push({
          severity: 'error',
          name: 'makeindex',
          text: groups.text,
          category: groups.category,
          log: reference,
          source: {
            file: groups.file,
            range: {
              start: line,
              end: line
            }
          }
        })
      }
    }])

    output.value = parsedLog

    return true
  }
}

@@ -584,16 +584,45 @@
  false%0A%0A
+    const name = 'makeindex'%0A
     cons
@@ -648,16 +648,16 @@
 Log = %7B%0A
-
       me
@@ -978,24 +978,164 @@
 ups.input))%0A
+        parsedLog.messages.push(%7B%0A          severity: 'info',%0A          name,%0A          text: groups._,%0A          log: reference%0A        %7D)%0A
       %7D%0A    
@@ -1278,32 +1278,32 @@
 e, groups) =%3E %7B%0A
-
         parsedLo
@@ -1348,24 +1348,740 @@
 ps.output))%0A
+        parsedLog.messages.push(%7B%0A          severity: 'info',%0A          name,%0A          text: groups._,%0A          log: reference%0A        %7D)%0A      %7D%0A    %7D, %7B%0A      names: %5B'text'%5D,%0A      patterns: %5B%0A        /%5E(Nothing written in .*?%5C.)$/%0A      %5D,%0A      evaluate: (reference, groups) =%3E %7B%0A        parsedLog.messages.push(%7B%0A          severity: 'warning',%0A          name,%0A          text: groups.text,%0A          log: reference%0A        %7D)%0A      %7D%0A    %7D, %7B%0A      names: %5B'text'%5D,%0A      patterns: %5B%0A        /%5E(Sorting entries.*)$/%0A      %5D,%0A      evaluate: (reference, groups) =%3E %7B%0A        parsedLog.messages.push(%7B%0A          severity: 'info',%0A          name,%0A          text: groups.text,%0A          log: reference%0A        %7D)%0A
       %7D%0A    

Add some more message patterns