#!/usr/bin/env ruby
#--
# Copyright (C) 2008-2009 Harald Sitter <apachelogger@ubuntu.com>
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License as
# published by the Free Software Foundation; either version 2 of
# the License or (at your option) version 3 or any later version
# accepted by the membership of KDE e.V. (or its successor approved
# by the membership of KDE e.V.), which shall act as a proxy
# defined in Section 14 of version 3 of the license.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program.  If not, see <http://www.gnu.org/licenses/>.
#--

# TODO: compile list of changes in .install
# TODO: pbuilder argument

require 'bat'

def debdiff
    pt "debdiffing"
    %x[cd ../batbranch && bzr diff > ../deb.diff]
end

def pbuild
    pt "pbuilding"
    time = Time.now.utc.strftime("%Y%m%d-%H%M%S")

    if File.exist?("build") and File.exist?("build/time-stamp")
        mv("build", "build-#{IO.readlines("build/time-stamp")[0]}")
    elsif File.exist?("build")
        mv("build", "build-pre-#{time}")
    end

    Dir.mkdir("build")
    pbuildexit = true
    system("cd #{Dir.pwd} && sudo #{@pbuilder} build --buildresult ./build --logfile ./build/BUILDLOG #{@app}_#{@version}.dsc")
    pbuildexit = false if $? != 0

    file = File.new( "build/time-stamp", File::CREAT | File::RDWR | File::TRUNC )
    file << time
    file.close
    return pbuildexit
end

def add_to_logs(name,var)
    var = [var] unless var.kind_of?(Array)
    @logs[name] = var
end

def parse_deblog
    dpkgsrc = []
    for line in DEBLOG.split("\n")
        if line.include?("dpkg-source") \
        and (line.include?("warning") or line.include?("error"))
            dpkgsrc += [line]
        end
    end
    add_to_logs("dpkg-source",dpkgsrc) unless dpkgsrc.empty?
end

def parse_buildlog
    if $options.build and File.exist?("build/BUILDLOG")
        file     = IO.readlines("build/BUILDLOG").join.split("\n")

        listmissing = []
        thestartl = file.index("STARTING LIST-MISSING HOOK")
        theendl = file.index{|x|x.include?("hooks") and x.include?("list-missing")}
        if thestartl and theendl
            for line in file[(thestartl+2)..(theendl-1)]
                listmissing += [line.gsub("-./","")]
            end
            add_to_logs("List-Missing",listmissing) unless listmissing.empty?
        end

        cmake = []
        thestartc = file.index{|x|x.include?("OPTIONAL packages could NOT be located")}
        theendc = thestartc + file[thestartc..-1].index{|x|x.include?("-----------------")} if thestartc
        if thestartc and theendc
            for line in file[(thestartc+2)..(theendc-1)]
                cmake += [line]
            end
            add_to_logs("CMAKE",cmake) unless cmake.empty?
        end
    end
end

def lintian_src
    lintiansrc = ""
    lintiansrc = %x[lintian #{@app}_#{@version}.dsc > /dev/stdout 2>&1].split("\n")
    add_to_logs("Lintian Source",lintiansrc) unless lintiansrc.empty?
end

def lintian_deb
    lintiandeb = ""
    for deb in Dir.glob("build/*.deb")
        lintiandeb = %x[lintian #{deb} > /dev/stdout 2>&1].split("\n")
    end
    add_to_logs("Lintian DEB",lintiandeb) unless lintiandeb.empty?
end

a = Optparser.new
$options.build = true
$options.diff = true
$options.report = true
$opts.on("-b", "--no-build", "Don't testbuild") do |nobuild|
    $options.build = nobuild
end
$opts.on("-d", "--no-diff", "Don't create diffs") do |nodiff|
    $options.diff = nodiff
end
$opts.on("-r", "--no-report", "Don't create a REPORT") do |noreport|
    $options.report = noreport
end
$opts.parse!(ARGV)

if File.basename(Dir.pwd) == "debian"
    Dir.chdir("..") # batbranch
end

Dir.chdir("..")
Dir.chdir(IO.readlines(".batsrc")[0].chop)

cp_r("../batbranch/debian",".")

checkCh
DEBLOG = debuild

debdiff if $options.diff and File.exist?("../batbranch/debian")

Dir.chdir("..") # source

if $options.build
    err("Pbuilder didn't exit properly.") unless pbuild
    rfile = "build/REPORT.build"
end

if $options.report
    @logs = {}
    pt("processing logs and getting further data")
    parse_deblog
    parse_buildlog
    lintian_src
    lintian_deb

    # if -b is set, pbuild() will not be started and build/ doesn't change, so
    # starting with -b after a build will ultimately result in an old REPORT.build
    # and this new REPORT in build/
    rfile = "build/REPORT" if rfile == nil

    unless @logs.empty?
        pt("writing report to #{rfile}")
        Dir.mkdir("build") unless File.exist?("build")
        file = File.new(rfile, File::CREAT | File::RDWR | File::TRUNC )
        @logs.each_key{ |x|
            file << "--------------------------------------------------------------\n"
            file << "#{x} sez:\n"
            file << "--------------------------------------------------------------\n"
            @logs[x].each{ |line|
                file << "#{line}\n"
            }
            file << "\n"
        }
        file.close
        system("kdialog --textbox #{rfile} 800 400 > /dev/null 2>&1")
    else
        wrn("either this package is in incredibly good shape, or there isn't enough data to gather for the report")
    end
end
