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
      File.open(@input) do |file|
        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")
          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.subsections.last
              section.subsections << subsection
            end
          end
          subsection.output << line if subsection

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