require 'cgi'
require 'erb'
require 'erubi'
require 'forwardable'
require 'json'
require 'pathname'

require 'debci'
require 'debci/job'
require 'debci/package'
require 'debci/package_status'
require 'debci/graph'
require 'debci/html_helpers'
require 'fileutils'

module Debci

  class HTML

    class << self
      def update
        Debci.config.suite_list.each do |suite|
          Debci.config.arch_list.each do |arch|
            json = Debci::HTML::JSON.new(suite, arch)
            json.status
            json.history
            json.packages
          end
        end
      end
    end

    class Rooted
      attr_reader :root, :datadir

      def initialize
        data_basedir = Debci.config.data_basedir
        @root = Pathname(data_basedir) / datadir
      end
    end

    class JSON < Rooted
      attr_accessor :suite, :arch

      def initialize(suite, arch)
        @datadir = 'status'
        super()
        self.suite = suite
        self.arch = arch
      end

      def status_packages_data
        @status_packages_data ||=
          Debci::PackageStatus.joins(:package).where(
            suite: suite,
            arch: arch,
            packages: { removed: false },
          ).includes(:job)
      end

      def status
        data = {
          pass: 0,
          fail: 0,
          neutral: 0,
          tmpfail: 0,
          total: 0,
        }
        status_packages_data.in_batches.each do |batch|
          batch.each do |package_status|
            status = package_status.job.status
            data[status.to_sym] += 1
            data[:total] += 1
          end
        end
        data[:date] = Time.now.strftime('%Y-%m-%dT%H:%M:%S')

        output = ::JSON.pretty_generate(data)

        today = root / suite / arch / Time.now.strftime('%Y/%m/%d.json')
        today.parent.mkpath
        today.write(output)

        current = root / suite / arch / 'status.json'
        current.write(output)
      end

      def history
        status_history = (root / suite / arch).glob('[0-9]*/[0-9]*/[0-9]*.json')
        status_history_data = status_history.sort.map { |f| ::JSON.parse(f.read) }

        h = root / suite / arch / 'history.json'
        h.write(::JSON.pretty_generate(status_history_data))
      end

      def packages
        p = root / suite / arch / 'packages.json'
        data = []
        status_packages_data.includes(job: :package).in_batches do |batch|
          batch.each do |status|
            data << status.job.public_api_attributes
          end
        end
        p.write(::JSON.pretty_generate(data.as_json))
      end
    end
  end
end
