using System;
using System.Text;
using System.Collections.Generic;

using CommonHelpers;

namespace SqlCatPP {

//**************************************************************************************************
static partial class Program {
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

static void PrintSyntax()
{
   HConsole.PrintIntensive(
      "=== {0} utility {1} ({2}): ===",
      SqlCatPP_Info.AssemblyName, //Assembly.GetEntryAssembly().GetName().Name
      SqlCatPP_Info.VersionStringExCON,
      SqlCatPP_Info.CopyrightCON );

   HConsole.PrintIntensive(
      "Supported parameters (valid \"...\" or empty: \"\",\"-\"):" );
   HConsole.PrintExpressive(
      "1) Settings script file (optional);\n"+
      "2) Script file pattern (conditionally optional);\n"+
      "3) Initial script file (optional);\n"+
      "4) Subfolder source pattern (conditionally optional);\n"+
      "5) Output script file (required)." );
   HConsole.Print(
      "Value \"-\" is treated as empty argument (\"\")." );

   HConsole.PrintIntensive(
      "Additional parameters-options (environment variables):" );
   HConsole.PrintExpressive(
      "{0} SqlCatPP.InsertSetVarComments {0}{0} use decorative script preprocessing: "+
      "1/0 (default: {1}, {0} {2});", DashChar,
      AdditionalParams.DefaultValues.InsertSetVarComments ? "1" : "0",
      AdditionalParams.DefaultValues.InsertSetVarComments ? OnValueName : OffValueName );
   HConsole.PrintExpressive(
      "{0} SqlCatPP.UnfoldEnvironmentVars {0}{0} unfold $(...) in decorative preprocessing: "+
      "1/0 (default: {1}, {0} {2});", DashChar,
      AdditionalParams.DefaultValues.UnfoldEnvironmentVars ? "1" : "0",
      AdditionalParams.DefaultValues.UnfoldEnvironmentVars ? OnValueName : OffValueName );
   HConsole.PrintExpressive(
      "{0} SqlCatPP.ProcessDirectives {0}{0} autonomously process \":SetVar\" and \":r\": "+
      "1/0 (default: {1}, {0} {2});", DashChar,
      AdditionalParams.DefaultValues.ProcessDirectives ? "1" : "0",
      AdditionalParams.DefaultValues.ProcessDirectives ? OnValueName : OffValueName );
   HConsole.PrintExpressive(
      "{0} SqlCatPP.OrderListErrorAsWarn {0}{0} nonstrict order-list error processing: "+
      "1/0 (default: {1}, {0} {2});", DashChar,
      AdditionalParams.DefaultValues.OrderListErrorAsWarn ? "1" : "0",
      AdditionalParams.DefaultValues.OrderListErrorAsWarn ? OnValueName : OffValueName );
   HConsole.PrintExpressive(
      "{0} SqlCatPP.AllowEmptyResult {0}{0} allow empty or quasi empty (settings only) script result: "+
      "1/0 (default: {1}, {0} {2});", DashChar,
      AdditionalParams.DefaultValues.AllowEmptyResult ? "1" : "0",
      AdditionalParams.DefaultValues.AllowEmptyResult ? OnValueName : OffValueName );
   HConsole.PrintExpressive(
      "{0} SqlCatPP.DefaultInputEncodingUTF8 {0}{0} by default for input files (if there is no BOM) treat them as in UTF-8 instead of ANSI-CP: "+
      "1/0 (default: {1}, {0} {2});", DashChar,
      AdditionalParams.DefaultValues.DefaultInputEncodingUTF8 ? "1" : "0",
      AdditionalParams.DefaultValues.DefaultInputEncodingUTF8 ? OnValueName : OffValueName );
   HConsole.PrintExpressive(
      "{0} SqlCatPP.CheckInputForANSI {0}{0} verify input characters exist in ANSI-CP: "+
      "1/0 (default: {1}, {0} {2});", DashChar,
      AdditionalParams.DefaultValues.CheckInputForANSI ? "1" : "0",
      AdditionalParams.DefaultValues.CheckInputForANSI ? OnValueName : OffValueName );
   HConsole.PrintExpressive(
      "{0} SqlCatPP.OutputAsANSI {0}{0} perform single byte encoding for output according to ANSI-CP: "+
      "1/0 (default: {1}, {0} {2});", DashChar,
      AdditionalParams.DefaultValues.OutputAsANSI ? "1" : "0",
      AdditionalParams.DefaultValues.OutputAsANSI ? OnValueName : OffValueName );
   HConsole.PrintExpressive(
      "{0} SqlCatPP.OutputFolderPath {0}{0} path to special output folder (for explicit output);", DashChar );
   HConsole.PrintExpressive(
      "{0} SqlCatPP.OutputFileName {0}{0} name of to special output file (for explicit output).", DashChar );

   HConsole.PrintIntensive(
      "Generated output parameters (options, environment vars):" );
   HConsole.PrintExpressive(
      "{0} SqlCatPP.Generated.GenerationOn {0}{0} perform generation (prepare multiple files):\n"+
      "  1/0 (default: {1}, {0} {2});", DashChar,
      AdditionalParams.DefaultValues.Generated_GenerationOn ? "1" : "0",
      AdditionalParams.DefaultValues.Generated_GenerationOn ? OnValueName : OffValueName );
   HConsole.PrintExpressive(
      "{0} SqlCatPP.Generated.FolderPath {0}{0} path to special folder for generated output;", DashChar );
   HConsole.PrintExpressive(
      "{0} SqlCatPP.Generated.CleanAllSQL {0}{0} remove all files in generated folder as preliminary:\n"+
      "  1/0 (default: {1}, {0} {2});", DashChar,
      AdditionalParams.DefaultValues.Generated_CleanAllSQL ? "1" : "0",
      AdditionalParams.DefaultValues.Generated_CleanAllSQL ? OnValueName : OffValueName );
   HConsole.PrintExpressive(
      "{0} SqlCatPP.Generated.OrderedWithCleanup {0}{0} output file-name ordering with preliminary or posteriour cleanup,\n"+
       "  with removal of all or all other files in generated folder:\n"+
      "  1/0 (default: {1}, {0} {2});", DashChar,
      AdditionalParams.DefaultValues.Generated_OrderedWithCleanup ? "1" : "0",
      AdditionalParams.DefaultValues.Generated_OrderedWithCleanup ? OnValueName : OffValueName );
   HConsole.PrintExpressive(
      "{0} SqlCatPP.Generated.OrderHeadingChar {0}{0} for output file-name ordering head (ANNN./BNNN./CNNN...):\n"+
      "  A..B, 0..9 (default: \"{1}\");", DashChar,
      AdditionalParams.DefaultValues.Generated_OrderHeadingChar );
   HConsole.PrintExpressive(
      "{0} SqlCatPP.Generated.EmbedFileNamesToOrder {0}{0} embed output file names (name altering) into existing alphabetical file order:\n"+
      "  1/0 (default: {1}, {0} {2});", DashChar,
      AdditionalParams.DefaultValues.Generated_EmbedFileNamesToOrder ? "1" : "0",
      AdditionalParams.DefaultValues.Generated_EmbedFileNamesToOrder ? OnValueName : OffValueName );
   HConsole.PrintExpressive(
      "{0} SqlCatPP.Generated.RestoreDateIfSameContent {0}{0} restore file modification date if content is same as previous:\n"+
      "  1/0 (default: {1}, {0} {2}).", DashChar,
      AdditionalParams.DefaultValues.Generated_RestoreDateIfSameContent ? "1" : "0",
      AdditionalParams.DefaultValues.Generated_RestoreDateIfSameContent ? OnValueName : OffValueName );

   HConsole.PrintIntensive(
      "Affecting files (if available):" );
   HConsole.PrintExpressive(
      "{0} $sql_order.list {0}{0} defines primary translation order "+
      "(to override default alphabet sorting).",
      DashChar );
   HConsole.Print(
      "\"!\"-prefixed item have the highest sorting priority, which prevails order in the list.\n"+
      "To change translation order of such an item, include it into \"$sql_order.list\".\n"+
      "To comment single translation line use \";\" (semicolon) at the very begining." );
   HConsole.PrintIntensive(
      "Files prefixed with \".\" (dot) must be specified in corresponding order list.\n"+
      "Files prefixed with \";\" (semicolon) are excluded from processing." );
}

//--------------------------------------------------------------------------------------------------

/// <exception cref="ArgumentNullException" />
static HAppFailureException CreateParameterError(int paramIdx,string message)
{
   HArgChecking.VerifyNotNull( message );
   return HAppFailureExceptionCreator.Create(
      "{0}\n"+
      "Parameter: {1} (argument number).",
      message, paramIdx+1 );
}
/// <exception cref="ArgumentNullException" />
static HAppFailureException CreateParameterError( int paramIdx,
                                                  string messageFmt,
                                                  params object[] parameters )
{
   return CreateParameterError( paramIdx, string.Format( messageFmt, parameters ) );
}

static string ArgumentNumDisplay(int paramIdx)
{
   return "#"+HInt32.ToNormalString( paramIdx+1 );
}

/// <exception cref="HAppFailureException" />
static void CheckParameterNormality(string value,int paramIdx)
{
   if ( HString.HasBoundaryWhiteSpace( value ) )
      throw CreateParameterError( paramIdx,
         "Parameter values must not have leading and/or trailing spaces." );
}

//--------------------------------------------------------------------------------------------------

/// <exception cref="ArgumentNullException" />
static void PrintInputItem(string filePath)
{
   HArgChecking.VerifyNotNull( filePath );
   HConsole.PrintIntensive( filePath );
}
/// <exception cref="ArgumentNullException" />
static void PrintInputItem([HOptional]string subfolderPath,IEnumerable<string> fileNames)
{
   HArgChecking.VerifyNotNull( subfolderPath );
   HArgChecking.VerifyNotNulls( fileNames );
   var sb = new StringBuilder( subfolderPath+":" );
   int idx = -1;
   foreach (var fileName in fileNames)
   {
      idx++;
      if ( idx > 0 )
         sb.Append( ',' );
      sb.Append( $" \"{fileName}\"" );
   }
   HConsole.PrintIntensive( sb.ToString() );
}

//==================================================================================================

const char DashChar = HConsole.DashChar;

static string OnValueName  => "on";
static string OffValueName => "off";

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
} // Program
//**************************************************************************************************

} // SqlCatPP
