require 'erb'
require 'zlib'

require 'debci'

module Debci
  class Log
    class Section
      attr_reader :name, :subsections, :output
      attr_accessor :result

      def initialize(name)
        @name = name
        @subsections = []
        @output = []
        @result = nil
      end

      def test?
        @result != nil
      end

      def inspect
        "<Section name=#{name.inspect} subsections=#{subsections.inspect} result=#{result.inspect}>"
      end
    end

    def initialize(logfile)
      @input = logfile
      @sections = []
    end

    attr_reader :sections

    def parse
      section = nil
      subsection = nil
      result = false
      file = File.open(@input)
      if @input =~ /\.gz/
        file = Zlib::GzipReader.new(file)
      end
      file.readlines.each do |line|
        line = line.scrub unless line.valid_encoding?
        case line
        when /^\s*\d+s autopkgtest \[\d\d:\d\d:\d\d\]: starting date and time/
          section = Section.new("Preparation")
          subsection = Section.new("start run")
        when /^\s*\d+s autopkgtest \[\d\d:\d\d:\d\d\]: @@@@@@@@@@@@@@@@@@@@ apt-source/
          subsection = Section.new("apt-source")
        when /^\s*\d+s autopkgtest \[\d\d:\d\d:\d\d\]: @@@@@@@@@@@@@@@@@@@@ test bed setup/
          subsection = Section.new("test bed setup")

        when /^\s*\d+s autopkgtest \[\d\d:\d\d:\d\d\]: test (.*): preparing testbed/
          section = Section.new("test #{::Regexp.last_match(1)}")
          subsection = Section.new("preparing testbed")
        when /^\s*\d+s autopkgtest \[\d\d:\d\d:\d\d\]: test (.*): \[-----------------------/
          subsection = Section.new("test run")
        when /^\s*\d+s autopkgtest \[[0-9:]+\]: test (\S+):  - - - - - - - - - - results - - - - - - - - - -/
          subsection = Section.new("test results")
          result = true
        when /^\s*\d+s autopkgtest \[\d\d:\d\d:\d\d\]: @@@@@@@@@@@@@@@@@@@@ (summary)/
          section = Section.new("Closing")
          subsection = Section.new("summary")
        when /^\s*\d+s\s+badpkg:\s+/
          section.result = "fail" unless section.name == "Closing"
        else
          # first line of non-autopkgtest log
          unless section
            section = Section.new("Log contents")
            subsection = section
          end
        end
        if section
          if section != self.sections.last
            self.sections << section
          end
          if subsection && subsection != section && subsection != section.subsections.last
            section.subsections << subsection
          end
        end
        subsection.output << line if subsection

        if section && result && line =~ /^\s*\d+s\s+\S+\s*(PASS|FAIL|SKIP)/
          section.result = ::Regexp.last_match(1).downcase
          result = false
        end
      end
    end
  end
end