<commit_before>﻿
open System

open Microsoft.Xrm.Sdk.Client

open DG.XrmDefinitelyTyped
open Utility
open CommandLineHelper


let getXrmAuth parsedArgs = 
  let ap = 
    getArg parsedArgs "ap" (fun ap ->
      Enum.Parse(typeof<AuthenticationProviderType>, ap) 
        :?> AuthenticationProviderType)

  { XrmAuthentication.url = Uri(Map.find "url" parsedArgs)
    username = Map.find "username" parsedArgs
    password = Map.find "password" parsedArgs
    domain = Map.tryFind "domain" parsedArgs
    ap = ap; }

let getRetrieveSettings parsedArgs =
  let entities = getListArg parsedArgs "entities" (fun s -> s.ToLower())
  let solutions = getListArg parsedArgs "solutions" id

  { XdtRetrievalSettings.entities = entities
    solutions = solutions
  }

let getGenerationSettings parsedArgs =
  let formIntersects = getListArg parsedArgs "formintersect" (fun definition -> 
    let nameSplit = definition.IndexOf(":")
    if nameSplit < 0 then failwithf "Missing name specification in form-intersect list at: '%s'" definition

    let name = definition.Substring(0, nameSplit) |> Utility.sanitizeString
    let list = definition.Substring(nameSplit + 1)

    let guidInput = list.Split(';')
    let guids = 
      guidInput
      |> Array.map Guid.TryParse
      |> Array.mapi (fun idx (r,g) ->
        if r then Some g
        else printfn "Unable to parse given form GUID: %s. Skipping it" guidInput.[idx]; None)
      |> Array.choose id
    name, guids)

  let nsSanitizer ns =
    if String.IsNullOrWhiteSpace ns then String.Empty
    else sanitizeString ns

  { XdtGenerationSettings.out = Map.tryFind "out" parsedArgs 
    jsLib = Map.tryFind "jsLib" parsedArgs 
    tsLib = Map.tryFind "tsLib" parsedArgs 
    crmVersion = getArg parsedArgs "crmVersion" parseVersion
    skipForms = getArg parsedArgs "skipForms" parseBoolish ?| false
    restNs = getArg parsedArgs "rest" nsSanitizer
    webNs = getArg parsedArgs "web" nsSanitizer
    formIntersects = formIntersects 
  }


/// Load metadata from local file and generate
let loadGen parsedArgs =
  let filename = 
    match Map.tryFind "load" parsedArgs with
    | Some p -> p
    | None -> failwithf "No load argument found"

  XrmDefinitelyTyped.GenerateFromFile(
    getGenerationSettings parsedArgs,
    filename)

/// Save metadata to file
let dataSave parsedArgs =
  let filename = 
    match Map.tryFind "save" parsedArgs with
    | Some p -> p
    | None -> failwithf "No load argument found"

  XrmDefinitelyTyped.SaveMetadataToFile(
      getXrmAuth parsedArgs, 
      getRetrieveSettings parsedArgs,
      filename)

// Regular connect to CRM and generate
let connectGen parsedArgs =
  XrmDefinitelyTyped.GenerateFromCrm(
    getXrmAuth parsedArgs, 
    getRetrieveSettings parsedArgs, 
    getGenerationSettings parsedArgs)


// Main executable function
let executeWithArgs argv =
  let parsedArgs = parseArgs argv Args.argMap

  match parsedArgs |> Map.tryPick (fun k v -> Args.flagArgMap.TryFind k) with
  | Some flagArg when flagArg = Args.genConfigFlag -> 
    Args.genConfig()

  | Some flagArg when flagArg = Args.loadFlag ->
    parsedArgs |> checkArgs Args.generationArgs |> loadGen

  | Some flagArg when flagArg = Args.saveFlag ->
    parsedArgs |> checkArgs Args.connectionArgs |> dataSave

  | _ -> 
    parsedArgs |> checkArgs Args.fullArgList |> connectGen


// Main method
[<EntryPoint>]
let main argv = 
  #if DEBUG
  executeWithArgs (List.ofArray argv)
  0
  #else
  try 
    showDescription()
    if argv.Length > 0 && Args.helpArgs.Contains argv.[0] then showUsage()
    else executeWithArgs (List.ofArray argv)
    0
  with ex ->
    eprintfn "%s" ex.Message
    1<commit_msg>Made executable generate config file if it does not exist and no arguments are given.<commit_after>﻿
open System

open Microsoft.Xrm.Sdk.Client

open DG.XrmDefinitelyTyped
open Utility
open CommandLineHelper


let getXrmAuth parsedArgs = 
  let ap = 
    getArg parsedArgs "ap" (fun ap ->
      Enum.Parse(typeof<AuthenticationProviderType>, ap) 
        :?> AuthenticationProviderType)

  { XrmAuthentication.url = Uri(Map.find "url" parsedArgs)
    username = Map.find "username" parsedArgs
    password = Map.find "password" parsedArgs
    domain = Map.tryFind "domain" parsedArgs
    ap = ap; }

let getRetrieveSettings parsedArgs =
  let entities = getListArg parsedArgs "entities" (fun s -> s.ToLower())
  let solutions = getListArg parsedArgs "solutions" id

  { XdtRetrievalSettings.entities = entities
    solutions = solutions
  }

let getGenerationSettings parsedArgs =
  let formIntersects = getListArg parsedArgs "formintersect" (fun definition -> 
    let nameSplit = definition.IndexOf(":")
    if nameSplit < 0 then failwithf "Missing name specification in form-intersect list at: '%s'" definition

    let name = definition.Substring(0, nameSplit) |> Utility.sanitizeString
    let list = definition.Substring(nameSplit + 1)

    let guidInput = list.Split(';')
    let guids = 
      guidInput
      |> Array.map Guid.TryParse
      |> Array.mapi (fun idx (r,g) ->
        if r then Some g
        else printfn "Unable to parse given form GUID: %s. Skipping it" guidInput.[idx]; None)
      |> Array.choose id
    name, guids)

  let nsSanitizer ns =
    if String.IsNullOrWhiteSpace ns then String.Empty
    else sanitizeString ns

  { XdtGenerationSettings.out = Map.tryFind "out" parsedArgs 
    jsLib = Map.tryFind "jsLib" parsedArgs 
    tsLib = Map.tryFind "tsLib" parsedArgs 
    crmVersion = getArg parsedArgs "crmVersion" parseVersion
    skipForms = getArg parsedArgs "skipForms" parseBoolish ?| false
    restNs = getArg parsedArgs "rest" nsSanitizer
    webNs = getArg parsedArgs "web" nsSanitizer
    formIntersects = formIntersects 
  }


/// Load metadata from local file and generate
let loadGen parsedArgs =
  let filename = 
    match Map.tryFind "load" parsedArgs with
    | Some p -> p
    | None -> failwithf "No load argument found"

  XrmDefinitelyTyped.GenerateFromFile(
    getGenerationSettings parsedArgs,
    filename)

/// Save metadata to file
let dataSave parsedArgs =
  let filename = 
    match Map.tryFind "save" parsedArgs with
    | Some p -> p
    | None -> failwithf "No load argument found"

  XrmDefinitelyTyped.SaveMetadataToFile(
      getXrmAuth parsedArgs, 
      getRetrieveSettings parsedArgs,
      filename)

// Regular connect to CRM and generate
let connectGen parsedArgs =
  XrmDefinitelyTyped.GenerateFromCrm(
    getXrmAuth parsedArgs, 
    getRetrieveSettings parsedArgs, 
    getGenerationSettings parsedArgs)


// Main executable function
let executeWithArgs argv =
  let parsedArgs = parseArgs argv Args.argMap

  match parsedArgs |> Map.tryPick (fun k _ -> Args.flagArgMap.TryFind k) with
  | Some flagArg when flagArg = Args.genConfigFlag -> 
    Args.genConfig()

  | Some flagArg when flagArg = Args.loadFlag ->
    parsedArgs |> checkArgs Args.generationArgs |> loadGen

  | Some flagArg when flagArg = Args.saveFlag ->
    parsedArgs |> checkArgs Args.connectionArgs |> dataSave

  | _ -> 
    parsedArgs |> checkArgs Args.fullArgList |> connectGen


// Main method
[<EntryPoint>]
let main argv = 
  #if DEBUG
  executeWithArgs (List.ofArray argv)
  0
  #else
  try 
    showDescription()
    if argv.Length > 0 && Args.helpArgs.Contains argv.[0] then showUsage()
    else if argv.Length = 0 && Args.configFileMissing() then 
      printfn "No configuration file found."
      Args.genConfig()
    else executeWithArgs (List.ofArray argv)

    0
  with ex ->
    eprintfn "%s" ex.Message
    1
{'fraction_non_alphanumeric': 0.0824387011265739, 'fraction_numerical': 0.0022531477799867462, 'mean_word_length': 3.3318025258323765, 'pattern_counts': {'":': 2, '<': 9, '<?xml version=': 0, '>': 61, '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': '6978029', 'n_tokens_mistral': 2316, 'n_tokens_neox': 2247, 'n_words': 694}