require 'time'
require 'whimsy/asf/yaml'

module ASF

  # Define super class to prevent circular references.  This class is
  # actually defined in ldap.rb which is require'd after committee.rb.
  class Base # :nodoc:
  end

  #
  # Representation for a committee (either a PMC, a board committee, or
  # a President's committee).  This data is parsed from
  # <tt>committee-info.txt|.yaml</tt>, and is augmened by data from LDAP,
  # and ASF::Mail.
  #
  # Note that the simple attributes which are sourced from
  # <tt>committee-info.txt</tt> data is generally not available until
  # ASF::Committee.load_committee_info is called.
  #
  # Similarly, the simple attributes which are sourced from LDAP is
  # generally not available until ASF::Project.preload is called.

  class Committee < Base
    # type of non-pmc entry (from its paragraph heading in committee-info.txt)
    attr_accessor :paragraph

    # list of chairs for this committee.  Returned as a list of hashes
    # containing the <tt>:name</tt> and <tt>:id</tt>.  Data is obtained from
    # <tt>committee-info.txt</tt>.
    attr_accessor :chairs

    # list of members for this committee.  Returned as a list of ids.
    # Data is obtained from <tt>committee-info.txt</tt>.
    attr_reader :info

    # when this committee is next expected to report.  May be a string
    # containing values such as "Next month: missing in May", "Next month: new,
    # monthly through July".  Data is obtained from <tt>committee-info.txt</tt>.
    attr_writer :report

    # list of members for this committee.  Returned as a list of hash
    # mapping ids to a hash of <tt>:name</tt> and <tt>:date</tt> values.
    # Data is obtained from <tt>committee-info.txt</tt>.
    attr_accessor :roster

    # Date this committee was established in the format MM/YYYY.
    # Data is obtained from <tt>committee-info.txt</tt>.
    attr_accessor :established

    # list of months when this committee typically reports.  Returned
    # as a comma separated string.  Data is obtained from
    # <tt>committee-info.txt</tt>.
    attr_accessor :schedule

    # create an empty committee instance
    def initialize(*args)
      @info = []
      @chairs = []
      @roster = {}
      super
    end

    # Original field sizes for PMC section
    NAMELEN = 26 # length of name field
    NAMEADDRLEN = 59 # length of name + email address fields (including separator)

    # mapping of committee names to canonical names (generally from ldap)
    # See also www/roster/committee.cgi
    @@aliases = Hash.new { |_hash, name| name.downcase}
    @@aliases.merge! \
      'brand management'               => 'brand',
      'c++ standard library'           => 'stdcxx',
      'community development'          => 'comdev',
      # TODO: are the concom entries correct? See INFRA-17782
      'conference planning'            => 'concom',
      'conferences'                    => 'concom',
      'distributed release audit tool' => 'drat',
      'diversity and inclusion'        => 'diversity',
      'http server'                    => 'httpd',
      'httpserver'                     => 'httpd',
      'incubating'                     => 'incubator', # special for index.html
      'java community process'         => 'jcp',
      'legal affairs'                  => 'legal',
      'logging services'               => 'logging',
      'lucene.net'                     => 'lucenenet',
      'open climate workbench'         => 'climate',
      'ocw'                            => 'climate', # is OCW used?
      'portable runtime'               => 'apr',
      'quetzalcoatl'                   => 'quetz',
      'security team'                  => 'security',
      'travel assistance'              => 'tac',
      'web services'                   => 'ws'

    @@namemap = proc do |name|
      # Drop parenthesized comments and downcase before lookup; drop all spaces after lookup
      # So aliases table does not need to contain entries for Traffic Server and XML Graphics.
      # Also compress white-space before lookup so tabs etc from index.html don't matter
      cname = @@aliases[name.sub(/\s+\(.*?\)/, '').strip.gsub(/\s+/, ' ').downcase].gsub(/\s+/, '')
      cname
    end

    # convert committee name to canonical name
    def self.to_canonical(name)
      @@namemap.call(name.downcase)
    end

    # load committee info from <tt>committee-info.txt</tt>.  Will not reparse
    # if the file has already been parsed and the underlying file has not
    # changed.
    # the parameters are currently only used by www/board/agenda/routes.rb
    def self.load_committee_info(contents = nil, info = nil)
      if contents
        if info
          @committee_mtime = @@svn_change =
            Time.parse(info[/Last Changed Date: (.*) \(/, 1]).gmtime
        else
          @committee_mtime = @@svn_change = Time.now
        end

        @nonpmcs, @officers, @committee_info = parse_committee_info_nocache(contents)
      else
        board = ASF::SVN.find('board')
        return unless board
        file = File.join(board, 'committee-info.txt')
        return unless File.exist? file

        if @committee_mtime and File.mtime(file) <= @committee_mtime
          return @committee_info if @committee_info
        end

        @committee_mtime = File.mtime(file)
        @@svn_change = Time.parse(ASF::SVN.getInfoItem(file, 'last-changed-date')).gmtime

        @nonpmcs, @officers, @committee_info = parse_committee_info_nocache(File.read(file))
      end
      @committee_info
    end

    # update next month section.  Remove entries that have reported or
    # or expired; add (or update) entries that are missing; add entries
    # for new committees.
    def self.update_next_month(contents, date, missing, rejected, todos)
      # extract next month section; and then extract the lines containing
      # '#' signs from within that section
      next_month = contents[/Next month.*?\n\n/m].chomp
      block = next_month[/(.*#.*\n)+/] || ''

      # remove expired entries
      month = date.strftime("%B")
      block.gsub!(/.* # new, monthly through #{month}\n/, '')

      # update/remove existing 'missing' entries
      existing = []
      block.gsub! %r{(.*?)# (missing|not accepted) in .*\n} do |line|
        if missing.include? $1.strip
          existing << $1.strip
          if line.chomp.end_with? month
            line
          elsif line.split(',').last.include? 'not accepted'
            "#{line.chomp}, missing #{month}\n"
          else
            "#{line.chomp}, #{month}\n"
          end
        elsif rejected.include? $1.strip
          existing << $1.strip
          if line.chomp.end_with? month
            line
          else
            "#{line.chomp}, not accepted #{month}\n"
          end
        else
          ''
        end
      end

      # add new 'missing' entries
      (missing - existing).each do |pmc|
        block += "    #{pmc.ljust(22)} # missing in #{month}\n"
      end

      # add new 'rejected' entries
      (rejected - missing - existing).each do |pmc|
        block += "    #{pmc.ljust(22)} # not accepted in #{month}\n"
      end

      # add new 'established' entries and remove 'terminated' entries
      month = (date + 91).strftime('%B')
      todos.each do |resolution|
        pmc = resolution['display_name']
        if resolution['action'] == 'terminate'
          block.sub! %r{^    #{Regexp.escape(pmc).ljust(22)} # .*\n}, ''
        elsif resolution['action'] == 'establish' and not existing.include? pmc
          block += "    #{pmc.ljust(22)} # new, monthly through #{month}\n"
        end
      end

      # replace/append block
      if next_month.include? '#'
        next_month[/(.*#.*\n)+/] = block.split("\n").sort.join("\n")
      else
        next_month += block
      end

      # replace next month section
      contents[/Next month.*?\n\n/m] = next_month + "\n\n"

      # return result
      contents
    end

    # update chairs
    def self.update_chairs(contents, todos)
      # extract committee section; and then extract the lines containing
      # committee names and chairs
      section = contents[/^1\..*?\n=+/m]
      committees = section[/-\n(.*?)\n\n/m, 1].scan(/^ +(.*?)  +(.*)/).to_h

      # update/add chairs based on resolutions
      todos.each do |resolution|
        name = resolution['display_name']
        if resolution['action'] == 'terminate'
          committees.delete(name)
        elsif resolution['chair']
          person = ASF::Person.find(resolution['chair'])
          committees[name] = "#{person.public_name} <#{person.id}@apache.org>"
        end
      end

      # sort and concatenate committees
      committees = committees.sort_by { |name, _chair| name.downcase }.
        map { |name, chair| "    #{name.ljust(23)} #{chair}" }.
        join("\n")

      # replace committee info in the section, and then replace the
      # section in the committee-info contents
      section[/-\n(.*?)\n\n/m, 1] = committees
      contents[/^1\..*?\n=+/m] = section

      # return result
      contents
    end

    # update roster for a project
    # Intended for use in ASF::SVN.update() block
    #
    # contents = current contents (normally provided by ASF::SVN.update); will be updated
    # cttee = committee id (lower case)
    # people = array of Person objects
    # action = add|remove
    # Note: ignores duplicate changes (e.g. if person to add is already present)
    def self.update_roster(contents, cttee, people, action)
      found = false
      contents.scan(/^\* (?:.|\n)*?\n\s*?\n/).each do |block|
        # find committee
        next unless ASF::Committee.find(block[/\* (.*?)\s+\(/, 1]).id == cttee

        # split block into lines
        lines = block.strip.split("\n")
        header = lines.shift
        # get the first line and use that to calculate the default offsets to use
        # This is done to avoid changing the spacing needlessly
        sample = lines.first
        namelen = NAMELEN # original
        nameaddrlen = NAMEADDRLEN # original
        # N.B. 4 spaces are assumed at the start
        if sample =~ %r{^    (\S.+) (<\S+?>\s+)\[}
          namelen = $1.size
          nameaddrlen = namelen + $2.size
        end
        # add or remove people
        # There are generally more people already in a PMC than are added or removed,
        # so try to scan the lines once
        # Get list of emails affected
        yyyymmdd = Time.new.gmtime.strftime('[%Y-%m-%d]')
        # gather list of potential new entries (some may be removed below)
        newentries = people.map do |person|
          [person.public_name, "<#{person.id}@apache.org>", yyyymmdd]
        end.to_a
        if action == 'add'
          # parse the lines so we can use format_pmc to recreate the entry, adjusting lengths if need be
          parsed = lines.map do |line|
            m = line.match(%r{^    (\S.+?) (<[^>]+>)\s+(\[\d.+)})
            if m
              newentries.reject! {|entry| m[2] == entry[1]}
              [m[1].strip, m[2], m[3]]
            else
              raise ArgumentError.new("Unexpected entry: #{line}")
            end
          end
          parsed += newentries
          lines = format_pmc(parsed, namelen, nameaddrlen)
        elsif action == 'remove'
          lines.reject! {|line| newentries.any? {|entry| line.include? entry[1]}}
        else
          raise ArgumentError.new("Expected action=[add|remove], found '#{action}'")
        end

        # replace committee block with new information
        contents.sub! block, ([header] + lines.sort).join("\n") + "\n\n"
        found = true
        break
      end
      raise ArgumentError.new("Could not find project id='#{cttee}'") unless found
      contents
    end

    # record termination date in committee-info.yaml
    # Params:
    # - input: the contents of committee-info.yaml
    # - pmc: the pmc name
    # - yyyymm: YYYY-MM retirement date
    #  Returns: the updated contents
    def self.record_termination(input, pmc, yyyymm)
      YamlFile.replace_section(input, :tlps) do |section, _yaml|
        key = ASF::Committee.to_canonical(pmc)
        if section[key]
          section[key][:retired] = yyyymm
          section[key][:name] = pmc
        else
          section[key] = {retired: yyyymm, name: pmc}
        end
        section.sort.to_h
      end
    end

    # remove committee from committee-info.txt
    def self.terminate(contents, pmc)
      ########################################################################
      #         remove from assigned quarterly reporting periods             #
      ########################################################################

      # split into blocks
      blocks = contents.split("\n\n")

      # find the reporting schedules
      index =  blocks.find_index {|section| section =~ /January/}

      # remove from each reporting period
      blocks[index + 0].sub! "\n    #{pmc}\n", "\n"
      blocks[index + 1].sub! "\n    #{pmc}\n", "\n"
      blocks[index + 2].sub! "\n    #{pmc}\n", "\n"

      # re-attach blocks
      contents = blocks.join("\n\n")

      ########################################################################
      #         remove from COMMITTEE MEMBERSHIP AND CHANGE PROCESS          #
      ########################################################################

      contents.sub! %r{^\* #{Regexp.escape(pmc)}  ?\(est.*?\n\n+}m, ''

      contents
    end

    # insert (replacing if necessary) a new committee into committee-info.txt
    def self.establish(contents, pmc, date, people)
      ########################################################################
      #         insert into assigned quarterly reporting periods             #
      ########################################################################

      # split into blocks
      blocks = contents.split("\n\n")

      # find the reporting schedules
      index =  blocks.find_index {|section| section =~ /January/}

      # extract reporting schedules
      slots = [
        blocks[index + 0].split("\n"),
        blocks[index + 1].split("\n"),
        blocks[index + 2].split("\n"),
      ]

      unless slots.any? {|slot| slot.include? "    " + pmc}
        # ensure that spacing is uniform
        slots.each {|slot| slot.unshift '' unless slot[0] == ''}

        # determine tie breakers between months of the same length
        preference = [(date.month) % 3, (date.month - 1) % 3, (date.month - 2) % 3]

        # pick the month with the shortest list
        slot = (0..2).map {|i| [slots[i].length, preference, i]}.min.last

        # temporarily remove headers
        headers = slots[slot].shift(3)

        # insert pmc into the reporting schedule
        slots[slot] << "    " + pmc

        # sort entries, case insensitive
        slots[slot].sort_by!(&:downcase)

        # restore headers
        slots[slot].unshift(*headers) # () are required here to prevent warning

        # re-insert reporting schedules
        blocks[index + 0] = slots[0].join("\n")
        blocks[index + 1] = slots[1].join("\n")
        blocks[index + 2] = slots[2].join("\n")

        # re-attach blocks
        contents = blocks.join("\n\n")
      end

      ########################################################################
      #         insert into COMMITTEE MEMBERSHIP AND CHANGE PROCESS          #
      ########################################################################

      # split into foot, sections (array) and head
      foot = contents[/^=+\s*\Z/]
      contents.sub! %r{^=+\s*\Z}, ''
      sections = contents.split(/^\* /)
      head = sections.shift

      # remove existing section (if present)
      sections.delete_if {|section| section.downcase.start_with? pmc.downcase}

      # build new section
      entries = people.map do |id, person|
        [person[:name], "<#{id}@apache.org>", "[#{date.strftime('%Y-%m-%d')}]"]
      end
      people = format_pmc(entries)

      section = ["#{pmc}  (est. #{date.strftime('%m/%Y')})"] + people.sort

      # add new section
      sections << section.join("\n") + "\n\n\n"

      # sort sections
      sections.sort_by!(&:downcase)

      # re-attach parts
      head + '* ' + sections.join('* ') + foot
    end

    # format a PMC entry
    # people: array of entries in the form [name, email, date+comment]
    # namelen: default size to allow for name field
    # nameaddrlen: default size to allow for name + email field
    # fields will be separated by at least one space on output
    # The defaults are taken from the originals to avoid needless change
    def self.format_pmc(people, namelen=NAMELEN, nameaddrlen=NAMEADDRLEN)
      maillen = 0
      people.each do |name, email, _datefield|
        namelen = [namelen, name.size].max
        maillen = [maillen, email.size].max
      end
      # +1 for space between fields
      nameaddrlen = [nameaddrlen, namelen + maillen + 1].max
      people.map do |name, email, datefield|
        nameaddr = "#{name.ljust(namelen)} #{email}"
        "    #{(nameaddr).ljust(nameaddrlen)} #{datefield}"
      end
    end

    # extract chairs, list of nonpmcs, roster, start date, and reporting
    # information from <tt>committee-info.txt</tt>.
    # @return nonpmcs, officers, committees (including nonpmcs)
    # This can safely be called with any input as it is idempotent
    # For general use, use ASF::Committee.load_committee_info
    # which caches the data
    def self.parse_committee_info_nocache(contents)
      # List uses full (display) names as keys, but the entries use the canonical names
      # - the local version of find() converts the name
      # - and stores the original as the display name if it has some upper case
      list = Hash.new {|hash, name| hash[name] = find(name, true)}

      # Split the file on lines starting "* ", i.e. the start of each group in section 3
      info = contents.split(/^\* /)
      # Extract the text before first entry in section 3 and split on section headers,
      # keeping sections 1 (COMMITTEES) and 2 (REPORTING).
      head, report = info.shift.split(/^\d\./)[1..2]
      # Drop lines which could match group headers
      head.gsub! %r{^\s+NAME\s+CHAIR\s*$}, ''
      head.gsub! %r{^\s+Office\s+Officer\s*$}i, ''

      # extract the committee chairs (e-mail address is required here)
      # Note: this includes the non-PMC entries

      # Scan for entries even if there is a missing extra space before the chair column
      head.scan(/^[ \t]+\w.*?[ \t]+.*[ \t]+<.*?@apache\.org>/).each do |line|
        # Now weed out the malformed lines
        m = line.match(/^[ \t]+(\w.*?)[ \t][ \t]+(.*)[ \t]+<(.*?)@apache\.org>/)
        if m
          committee, name, id = m.captures
          unless list[committee].chairs.any? {|chair| chair[:id] == id}
            list[committee].chairs << {name: name, id: id}
          end
        else
          # not possible to determine where one name starts and the other begins
          Wunderbar.warn "Missing separator before chair name in: '#{line}'"
        end
      end
      # Extract the non-PMC committees (e-mail address may be absent)
      # first drop leading text (and Officers) so we only match non-PMCs
      nonpmcs = head.sub(/.*?also has /m, '').sub(/ Officers:.*/m, '').
        scan(/^[ \t]+(\w.*?)(?:[ \t][ \t]|[ \t]?$)/).flatten.uniq.
        map {|name| list[name]}

      # Extract officers
      # first drop leading text so we only match officers at end of section
      officers = head.sub(/.*?also has .*? Officers/m, '').
        scan(/^[ \t]+(\w.*?)(?:[ \t][ \t]|[ \t]?$)/).flatten.uniq.
        map {|name| list[name]}

      # store the paragraph identifiers: Board Committees etc
      head_parts = head.split(/^The ASF also has the following +/)
      (1..head_parts.size - 1).each do |h| # skip the first section
        part = head_parts[h]
        type = part[/^([^:]+)/, 1] # capture remains of line excluding colon
        part.scan(/^[ \t]+(\w.*?)(?:[ \t][ \t]|[ \t]?$)/).flatten.uniq.each do |cttee|
          list[cttee].paragraph = type
        end
      end

      # for each committee in section 3
      info.each do |roster|
        # extract the committee name (and parenthesised comment if any)
        name = roster[/(\w.*?)[ \t]+\(est/, 1]
        unless list.include?(name)
          Wunderbar.warn "No chair entry detected for #{name} in section 3"
        end
        committee = list[name]

        # get and normalize the start date
        established = roster[/\(est\. (.*?)\)/, 1]
        established = "0#{established}" if established =~ /^\d\//
        committee.established = established

        # match non-empty entries and check the syntax
        roster.scan(/^[ \t]+.+$/) do |line|
          Wunderbar.warn "Invalid syntax: #{committee.name} '#{line}'" unless line =~ /\s<(.*?)@apache\.org>\s/
        end

        # extract the availids (is this used?)
        committee.info = roster.scan(/<(.*?)@apache\.org>/).flatten

        # drop (chair) markers and extract 0: name, 1: availid, 2: [date], 3: date
        # the date is optional (e.g. infrastructure)
        committee.roster = Hash[roster.gsub(/\(\w+\)/, '').
          scan(/^[ \t]*(.*?)[ \t]*<(.*?)@apache\.org>(?:[ \t]+(\[(.*?)\]))?/).
          map {|l| [l[1], {name: l[0], date: l[3]}]}]
      end

      # process report section
      report.scan(/^([^\n]+)\n---+\n(.*?)\n\n/m).each do |period, committees|
        committees.scan(/^   [ \t]*(.*)/).each do |committee|
          committee, comment = committee.first.split(/[ \t]+#[ \t]+/, 2)
          unless list.include? committee
            Wunderbar.warn "Unexpected name '#{committee}' in report section; ignored"
            next
          end
          committee = list[committee]
          if comment
            committee.report = "#{period}: #{comment}"
          elsif period == 'Next month'
            committee.report = 'Every month'
          else
            committee.schedule = period
          end
        end
      end
      committee_info = (list.values - officers).uniq
      # Check if there are duplicates.
      committee_info.each do |c|
        if c.chairs.length != 1 && c.name != 'fundraising' # hack to avoid reporting non-PMC entry
          Wunderbar.warn "Unexpected chair count for #{c.display_name}: #{c.chairs.inspect rescue ''}"
        end
      end
      return nonpmcs, officers, committee_info
    end

    # return a list of PMC committees.  Data is obtained from
    # <tt>committee-info.txt</tt>
    def self.pmcs
      committees = ASF::Committee.load_committee_info
      committees - @nonpmcs - @officers
    end

    # return a list of non-PMC committees.  Data is obtained from
    # <tt>committee-info.txt</tt>
    def self.nonpmcs
      ASF::Committee.load_committee_info # ensure data exists
      @nonpmcs
    end

    # return a list of officers.  Data is obtained from
    # <tt>committee-info.txt</tt>.  Note that these entries are returned
    # as instances of ASF::Committee with display_name being the name of
    # the office, and chairs being the individuals who hold that office.
    def self.officers
      ASF::Committee.load_committee_info # ensure data exists
      @officers
    end

    # look up an individual officer
    def self.officer(role)
      office = self.officers.find {|officer| officer.name == role}
      office && ASF::Person.find(office.chairs.first[:id])
    end

    # Finds a committee based on the name of the Committee.  Is aware of
    # a number of aliases for a given committee.  Will set display name
    # if the name being searched on contains an uppercase character.
    # If clear is true, then remove any cached entry
    def self.find(name, clear=false)
      raise ArgumentError.new('name: must not be nil') unless name
      namelc = @@namemap.call(name.downcase)
      collection[namelc] = nil if clear
      result = super(namelc)
      result.display_name = name if name =~ /[A-Z]/
      result
    end

    # Return the Last Changed Date for <tt>committee-info.txt</tt> in svn as
    # a <tt>Time</tt> object.  Data is based on the previous call to
    # ASF::Committee.load_committee_info.
    def self.svn_change
      @@svn_change
    end

    # returns the (first) chair as an instance of the ASF::Person class.
    def chair
      Committee.load_committee_info
      if @chairs.length >= 1
        ASF::Person.find(@chairs.first[:id])
      else
        nil
      end
    end

    # Version of name suitable for display purposes.  Typically in uppercase.
    # Data is sourced from <tt>committee-info.txt</tt>.
    def display_name
      Committee.load_committee_info
      @display_name || name
    end

    # setter for display_name, should only be used by
    # ASF::Committee.load_committee_info
    def display_name=(name)
      @display_name ||= name
    end

    # when this committee is next expected to report.  May be a string
    # containing values such as "Next month: missing in May", "Next month: new,
    # monthly through July".  Or may be a list of months, separated by commas.
    # Data is obtained from <tt>committee-info.txt</tt>.
    def report
      @report || @schedule
    end

    # setter for display_name, should only be used by
    # ASF::Committee.load_committee_info
    def info=(list)
      @info = list
    end

    # hash of availid => public_name for members (owners) of this committee
    # Data is obtained from <tt>committee-info.txt</tt>.
    def names
      Committee.load_committee_info
      Hash[@roster.map {|id, info| [id, info[:name]]}]
    end

    # if true, this committee is not a PMC.
    # Data is obtained from <tt>committee-info.txt</tt>.
    def nonpmc?
      Committee.load_committee_info # ensure data is there
      Committee.nonpmcs.include? self
    end

    # if true, this committee is a PMC.
    # Data is obtained from <tt>committee-info.txt</tt>.
    def pmc?
      Committee.load_committee_info # ensure data is there
      Committee.pmcs.include? self
    end

    # load committee metadata from <tt>committee-info.yaml</tt>.  Will not reparse
    # if the file has already been parsed and the underlying file has not changed.
    def self.load_committee_metadata
      board = ASF::SVN.find('board')
      return unless board
      file = File.join(board, 'committee-info.yaml')
      return unless File.exist? file

      return @committee_metadata if @committee_metadata and @committee_metadata_mtime and File.mtime(file) <= @committee_metadata_mtime

      @committee_metadata_mtime = File.mtime(file)
      @committee_metadata = YAML.load_file file
    end

    # get the changed date for the meta data
    def self.meta_change
      @committee_metadata_mtime
    end

    # get the metadata for a given committee.
    def self.metadata(committee)
      committee = committee.name if committee.is_a? ASF::Committee
      load_committee_metadata[:tlps][committee] || load_committee_metadata[:cttees][committee]
    end

    # website for this committee.
    def site
      meta = ASF::Committee.metadata(name)
      meta[:site] if meta
    end

    # description for this committee.
    def description
      meta = ASF::Committee.metadata(name)
      meta[:description] if meta
    end

    # append the description for a new tlp committee.
    # this is intended to be called from todos.json.rb in the block for ASF::SVN.update
    def self.appendtlpmetadata(input, committee, description, date_established)
      YamlFile.replace_section(input, :tlps) do |section, yaml|
        output = section # default no change
        if yaml[:cttees][committee] && !yaml[:cttees][committee][:retired]
          Wunderbar.warn "Entry for '#{committee}' already exists under :cttees"
        elsif yaml[:tlps][committee] && !yaml[:tlps][committee][:retired]
          Wunderbar.warn "Entry for '#{committee}' already exists under :tlps"
        else
          if section[committee] # already exists; must be retired
            diary = section[committee][:diary]
            if !diary
                diary = section[committee][:diary] = []
                diary << {established: section[committee][:established]}
            end
            diary << {retired: section[committee].delete(:retired)}
            diary << {resumed: date_established.strftime('%Y-%m')}
          else
            section[committee] = {
                site: "http://#{committee}.apache.org",
                description: description,
                established: date_established.strftime('%Y-%m'),
            }
          end
          output = section.sort.to_h
        end
        output
      end
    end

  end
end
