desc "Build the hook
    DEBUG - build plugins in debug mode - default: false"
task :build do
    flags = []
    if ENV["DEBUG"] == "true"
        flags.append "-gcflags", "all=-N -l"
    end

    # Prepend the common prefix for all server hooks. The motivations for this
    # were discussed in https://gitlab.isc.org/isc-projects/stork-hook-ldap/-/merge_requests/1#note_403065 .
    hook_name = "stork-server-ldap.so"

    build_dir = "build"
    sh "mkdir", "-p", build_dir
    sh "rm", "-f", *FileList[File.join(build_dir, "*.so")]

    output_path = File.expand_path File.join(build_dir, hook_name)

    Dir.chdir "src" do
        sh "go", "mod", "tidy"
        sh "go", "build", *flags, "-buildmode=plugin", "-o", output_path
    end

    size = File.size output_path
    size /= 1024.0 * 1024.0
    puts "Hook: '#{output_path}' size: #{'%.2f' % size} MiB"
end

desc "Lint the hook"
task :lint do
    Dir.chdir "src" do
        sh "go", "vet", "./..."
    end
end

desc "Run hook unit tests"
task :unittest do
    Dir.chdir "src" do
        at_exit {
            sh "rm -f src/coverage.out"
        }
        sh "go", "test", "-coverprofile=coverage.out", "-race", "-v", "./..."
        out = `go tool cover -func=coverage.out`
        puts out, ''
        low_coverage = false
        ignored_function_now_covered = false
        coverage_threshold = 100
        out.each_line do |line|
            if line.start_with? 'total:'
                next
            end

            items = line.gsub(/\s+/m, ' ').strip.split(" ")
            file = items[0].gsub(/:\d+:/, "")
            func = items[1]
            cov = items[2].strip()[0..-2].to_f
            rel_path = file.gsub("isc.org/stork-hook-ldap/", "src/")
            file_func = rel_path + ": " + func

            ignore_list = [
                # Functions that had 0% coverage at the time coverage was added.
                "src/callouts.go: Authenticate",
                "src/callouts.go: Close",
                "src/callouts.go: GetMetadata",
                "src/callouts.go: Unauthenticate",
                "src/internal/controller.go: Close",
                "src/internal/driver.go: Close",
                "src/internal/driver.go: Dial",
                "src/internal/driver.go: NewLDAPLibraryDriver",
                "src/internal/driver.go: Search",
                "src/internal/driver.go: SimpleBind",
            ]
            if cov < coverage_threshold and not ignore_list.include? file_func
                puts "FAIL: %-80s %5s%% < %s%%" % ["#{rel_path} #{func}", "#{cov}", "#{coverage_threshold}"]
                low_coverage = true
            end
            if cov >= coverage_threshold and ignore_list.include? file_func
                puts "FAIL: %-80s %5s%% >= %s%%" % ["#{rel_path} #{func}", "#{cov}", "#{coverage_threshold}"]
                ignored_function_now_covered = true
            end
        end
        if low_coverage
            fail("\nFAIL: Tests coverage is too low. Add some tests.\n\n")
        end
        if ignored_function_now_covered
            fail("\nFAIL: Ignored function is now covered. Take it out of the ignore list.\n\n")
        end
    end
end

desc "Format code"
task :fmt do
    Dir.chdir "src" do
        sh "go", "fmt", "./..."
    end
end
