<commit_before>#
# ActiveFacts Compositions, Metamodel aspect to create a textual summary of a composition and its Composites
# 
# Copyright (c) 2015 <NAME>. Read the LICENSE file.
#
require "activefacts/metamodel"
require "activefacts/compositions/names"
require "activefacts/compositions/constraints"
require "activefacts/generator"

module ActiveFacts
  module Metamodel
    class Composition
      def summary
        classify_constraints
        "Summary of #{name}\n" +
        all_composite.
        sort_by{|composite| composite.mapping.name}.
        flat_map do |composite|
          composite.summary
        end*''
      end
    end

    class Composite
      def summary
        indices = self.all_indices_by_rank

        (
          [mapping.name+"\n"] +
          mapping.
          leaves.
          reject{|leaf| leaf.is_a?(Absorption) && leaf.forward_absorption}.
          flat_map do |leaf|

            # Build a display of the names in this absorption path, with FK and optional indicators
            path_names = leaf.path.map do |component|
                is_mandatory = case component
                  when Indicator
                    false
                  when Absorption
                    component.parent_role.is_mandatory
                  else
                    true
                  end

                if component.is_a?(Absorption) && component.foreign_key
                  "[#{component.name}]"
                else
                  component.name
                end +
                  (is_mandatory ? '' : '?')
              end*'->' 

            # Build a symbolic representation of the index participation of this leaf
            pos = 0
            indexing = indices.inject([]) do |a, index|
              pos += 1
              if part = index.position_in_index(leaf)
                a << "#{pos}.#{part}"
              end
              a
            end
            if indexing.empty? 
              indexing = '' 
            else
              indexing = "[#{indexing*','}]"
            end

            column_name = leaf.column_name.capwords*' '
            ["\t#{path_names}#{indexing} as #{column_name.inspect}\n"] +
            leaf.all_leaf_constraint.map{|leaf_constraint| "\t\t### #{leaf_constraint.leaf_constraint.describe}\n"}
          end +
          all_local_constraint.map do |local_constraint|
            "\t### #{local_constraint.local_constraint.describe}\n"
          end.sort +
          all_spanning_constraint.map do |spanning_constraint|
            "### #{spanning_constraint.spanning_constraint.describe}\n"
          end.sort

        )*''
      end
    end
  end

  module Generators
    class Summary
      def self.options
        {
        }
      end

      def initialize composition
        @composition = composition
      end

      def generate<commit_msg>Summary generator did not expect options<commit_after>#
# ActiveFacts Compositions, Metamodel aspect to create a textual summary of a composition and its Composites
# 
# Copyright (c) 2015 <NAME>. Read the LICENSE file.
#
require "activefacts/metamodel"
require "activefacts/compositions/names"
require "activefacts/compositions/constraints"
require "activefacts/generator"

module ActiveFacts
  module Metamodel
    class Composition
      def summary
        classify_constraints
        "Summary of #{name}\n" +
        all_composite.
        sort_by{|composite| composite.mapping.name}.
        flat_map do |composite|
          composite.summary
        end*''
      end
    end

    class Composite
      def summary
        indices = self.all_indices_by_rank

        (
          [mapping.name+"\n"] +
          mapping.
          leaves.
          reject{|leaf| leaf.is_a?(Absorption) && leaf.forward_absorption}.
          flat_map do |leaf|

            # Build a display of the names in this absorption path, with FK and optional indicators
            path_names = leaf.path.map do |component|
                is_mandatory = case component
                  when Indicator
                    false
                  when Absorption
                    component.parent_role.is_mandatory
                  else
                    true
                  end

                if component.is_a?(Absorption) && component.foreign_key
                  "[#{component.name}]"
                else
                  component.name
                end +
                  (is_mandatory ? '' : '?')
              end*'->' 

            # Build a symbolic representation of the index participation of this leaf
            pos = 0
            indexing = indices.inject([]) do |a, index|
              pos += 1
              if part = index.position_in_index(leaf)
                a << "#{pos}.#{part}"
              end
              a
            end
            if indexing.empty? 
              indexing = '' 
            else
              indexing = "[#{indexing*','}]"
            end

            column_name = leaf.column_name.capwords*' '
            ["\t#{path_names}#{indexing} as #{column_name.inspect}\n"] +
            leaf.all_leaf_constraint.map{|leaf_constraint| "\t\t### #{leaf_constraint.leaf_constraint.describe}\n"}
          end +
          all_local_constraint.map do |local_constraint|
            "\t### #{local_constraint.local_constraint.describe}\n"
          end.sort +
          all_spanning_constraint.map do |spanning_constraint|
            "### #{spanning_constraint.spanning_constraint.describe}\n"
          end.sort

        )*''
      end
    end
  end

  module Generators
    class Summary
      def self.options
        {
        }
      end

      def initialize composition, options = {}
        @composition = composition
        @options = options
      end

      def generate
{'fraction_non_alphanumeric': 0.08647526807333103, 'fraction_numerical': 0.0020754064337599448, 'mean_word_length': 1.5816964285714286, 'pattern_counts': {'":': 0, '<': 9, '<?xml version=': 0, '>': 7, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1992511', 'n_tokens_mistral': 1574, 'n_tokens_neox': 1465, 'n_words': 371}