<commit_before>module Graph exposing (Graph, decode, empty, encode, init, run)

import AST.Types as AST
import Analyser.FileContext as FileContext exposing (FileContext)
import Analyser.Files.Types exposing (Dependency, LoadedSourceFiles)
import Dict exposing (Dict)
import Graph.Color as Color exposing (Color)
import Graph.Edge as Edge exposing (Edge)
import Graph.Node as Node exposing (Node)
import Json.Decode as JD exposing (Decoder)
import Json.Decode.Extra exposing ((|:))
import Json.Encode as JE exposing (Value)
import List.Extra as List
import Set


type alias Graph =
    { edges : List Edge
    , nodes : List Node
    }


empty : Graph
empty =
    init [] []


init : List Edge -> List Node -> Graph
init =
    Graph


run : LoadedSourceFiles -> List Dependency -> Graph
run sources deps =
    let
        files =
            List.filterMap (FileContext.create sources deps) sources

        moduleNames =
            List.filterMap .moduleName files

        moduleColors =
            colors moduleNames

        nodes =
            List.map (nodeFromFile moduleColors) moduleNames

        identifiers =
            List.map .identifier nodes
                |> Set.fromList

        edges =
            List.map edgesInFile files
                |> List.concat
                |> -- edges to external node (not included in nodes)
                   -- must be filtered out to create a valid graph
                   Edge.filterForIdentifiers identifiers
    in
        init edges nodes


topModuleName : AST.ModuleName -> String
topModuleName moduleNameAST =
    List.head moduleNameAST
        |> Maybe.withDefault "Unknown"


colors : List AST.ModuleName -> Dict String Color
colors moduleNames =
    let
        topModuleNames =
            List.map topModuleName moduleNames
                |> Set.fromList
                |> Set.toList
                |> List.sort

        allColors =
            Color.list

        colorsLength =
            List.length allColors

        colorsForModuleNames =
            topModuleNames
                |> List.indexedMap
                    (\index name ->
                        let
                            color =
                                List.getAt (index % colorsLength) allColors
                                    |> Maybe.withDefault Color.fallback
                        in
                            ( name, color )
                    )<commit_msg>Clarify definition of edges to external nodes<commit_after>module Graph exposing (Graph, decode, empty, encode, init, run)

import AST.Types as AST
import Analyser.FileContext as FileContext exposing (FileContext)
import Analyser.Files.Types exposing (Dependency, LoadedSourceFiles)
import Dict exposing (Dict)
import Graph.Color as Color exposing (Color)
import Graph.Edge as Edge exposing (Edge)
import Graph.Node as Node exposing (Node)
import Json.Decode as JD exposing (Decoder)
import Json.Decode.Extra exposing ((|:))
import Json.Encode as JE exposing (Value)
import List.Extra as List
import Set


type alias Graph =
    { edges : List Edge
    , nodes : List Node
    }


empty : Graph
empty =
    init [] []


init : List Edge -> List Node -> Graph
init =
    Graph


run : LoadedSourceFiles -> List Dependency -> Graph
run sources deps =
    let
        files =
            List.filterMap (FileContext.create sources deps) sources

        moduleNames =
            List.filterMap .moduleName files

        moduleColors =
            colors moduleNames

        nodes =
            List.map (nodeFromFile moduleColors) moduleNames

        identifiers =
            List.map .identifier nodes
                |> Set.fromList

        {-
           Edges to external nodes (i.e. dependencies outside of the scope of
           this app, such as Core and external packages) must be filtered out
           in order to create a valid graph (as these dependencies are not
           represented in the files and hence are missing from the nodes).
        -}
        removeEdgesToDependecies =
            Edge.filterForIdentifiers identifiers

        edges =
            List.map edgesInFile files
                |> List.concat
                |> removeEdgesToDependecies
    in
        init edges nodes


topModuleName : AST.ModuleName -> String
topModuleName moduleNameAST =
    List.head moduleNameAST
        |> Maybe.withDefault "Unknown"


colors : List AST.ModuleName -> Dict String Color
colors moduleNames =
    let
        topModuleNames =
            List.map topModuleName moduleNames
                |> Set.fromList
                |> Set.toList
                |> List.sort

        allColors =
            Color.list

        colorsLength =
            List.length allColors

        colorsForModuleNames =
            topModuleNames
                |> List.indexedMap
                    (\index name ->
                        List.getAt (index % colorsLength) allColors
                            |> Maybe.withDefault Color.fallback
                            |> (,) name
                    )
{'fraction_non_alphanumeric': 0.062450592885375494, 'fraction_numerical': 0.0, 'mean_word_length': 1.7445770065075923, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 36, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 2, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '4758312', 'n_tokens_mistral': 1301, 'n_tokens_neox': 1198, 'n_words': 421}