unit uclusterconfig;

{$mode delphi}

interface

uses
  Classes, urosx, SysUtils, uConstantesSimSEE;

const
  VERSION_Cluster_CONFIG = 2;

type

  { TClusterConfigPerfil }

  TClusterConfigPerfil = class
    nombrePerfil: string;
    Usuario: string;
    Clave: string;
    email: string;
    host: string;
    archiPrivateKey: string;
    particion: string;
    constructor CreateDefault;
    constructor CreateReadFromText(var fconfig: textfile; version: integer);
    procedure WriteToText(var fconfig: textfile);
    function CreateClone: TClusterConfigPerfil;
  end;

  { TClusterConfigRec }
  TClusterConfigRec = class
    Version: integer;
    perfiles: TList;
    kPerfilActivo: integer;
    particion: string;

    // Guarda la configuración
    procedure Save;

    // no use estas funciones, en lugar de ello use get_Cluster_cfg
    constructor CreateLoad;
    constructor CreateEmpty;

    function NombresPerfiles: TStringList;
    function PerfilActivo: TClusterConfigPerfil;
    function GetPerfil(nombre: string): TClusterConfigPerfil;
  end;

// Si aún no fue leida/creada la lee o la crea y retorna puntero.
function get_Cluster_cfg: TClusterConfigRec;


implementation

uses
  uclusterconf_formulario;

var
  Cluster_cfg: TClusterConfigRec;

// Si aún no fue leida/creada la lee o la crea y retorna puntero.
function get_Cluster_cfg: TClusterConfigRec;
var
  f: uclusterconf_formulario.TFormConfiguracionPerfilesSSH;
begin
  if Cluster_cfg = nil then
  begin
    Cluster_cfg := TClusterConfigRec.CreateLoad;
    f := uclusterconf_formulario.TFormConfiguracionPerfilesSSH.Create(nil);
    f.LoadConfig;
    f.ShowModal;
    f.Free;
  end;
  Result := Cluster_cfg;
end;

function archi_Cluster_cfg: string;
begin
  Result := getDir_Bin + 'Cluster.cfg';
end;

function getpal(var fconfig: textfile): string;
var
  pal: string;
begin
  if not EOF(fconfig) then
  begin
    readln(fconfig, pal);
    Result := desbarullar(pal);
  end
  else
    Result := '';
end;


{ TClusterConfigPerfil }

constructor TClusterConfigPerfil.CreateDefault;
begin
  NombrePerfil := 'Por defecto';
  Usuario := '???';
  Clave := '';
  email := '???';
  host := '???';
  particion:= '???';
  archiPrivateKey := '???archivo de clave privada';
end;

constructor TClusterConfigPerfil.CreateReadFromText(var fconfig: textfile;
  version: integer);
begin
  NombrePerfil := getpal(fconfig);
  Usuario := getpal(fconfig);
  Clave := getpal(fconfig);
  email := getpal(fconfig);
  host := getpal(fconfig);
  archiPrivateKey := getpal(fconfig);
  if version > 1 then
    particion := getpal(fconfig)
  else
  begin
    if pos('@ute', email) > 0 then
      particion := 'ute'
    else
      particion := 'normal';
  end;
end;

procedure TClusterConfigPerfil.WriteToText(var fconfig: textfile);
begin
  writeln(fconfig, barullar(NombrePerfil));
  writeln(fconfig, barullar(Usuario));
  writeln(fconfig, barullar(Clave));
  writeln(fconfig, barullar(Email));
  writeln(fconfig, barullar(Host));
  writeln(fconfig, barullar(archiPrivateKey));
  writeln(fconfig, barullar(particion));
end;

function TClusterConfigPerfil.CreateClone: TClusterConfigPerfil;
var
  aPerfil: TClusterConfigPerfil;
begin
  aPerfil := TClusterConfigPerfil.CreateDefault;
  aPerfil.nombrePerfil := '_clon_';
  aPerfil.Usuario := Usuario;
  aPerfil.Clave := Clave;
  aPerfil.email := email;
  aPerfil.host := host;
  aPerfil.particion := particion;
  aPerfil.archiPrivateKey := archiPrivateKey;
  Result := aPerfil;
end;

{ TClusterConfigRec }

constructor TClusterConfigRec.CreateLoad;
var
  fconfig: textfile;
  archi: string;
  OldFileMode: byte;
  NPerfiles: integer;
  kPerfil: integer;
  aPerfil: TClusterConfigPerfil;

begin
  CreateEmpty;
  archi := archi_Cluster_cfg;
  if fileexists(archi) then
    try
      OldFileMode := filemode;
      filemode := 0;
      assignfile(fconfig, archi);
      reset(fconfig);
      readln(fconfig, version); // versión del archivo

      for kPerfil := 0 to Perfiles.Count - 1 do
      begin
        aPerfil := Perfiles[kPerfil];
        aPerfil.Free;
      end;
      Perfiles.Clear;

      readln(fconfig, kPerfilActivo);
      readln(fconfig, NPerfiles);

      for kPerfil := 1 to NPerfiles do
      begin
        aPerfil := TClusterConfigPerfil.CreateReadFromText(fconfig, version);
        Perfiles.Add(aPerfil);
      end;
      closefile(fconfig);
    except
      // nada
    end;
  fileMode := OldFileMode;
end;


constructor TClusterConfigRec.CreateEmpty;
begin
  inherited Create;
  Perfiles := TList.Create;
  Perfiles.add(TClusterConfigPerfil.CreateDefault);
  kPerfilActivo := 0;
end;

function TClusterConfigRec.NombresPerfiles: TStringList;
var
  res: TStringList;
  kPerfil: integer;
  aPerfil: TClusterConfigPerfil;
begin
  res := TStringList.Create;
  for kPerfil := 0 to Perfiles.Count - 1 do
  begin
    aPerfil := Perfiles[kPerfil];
    res.add(aPerfil.nombrePerfil);
  end;
  Result := res;
end;

function TClusterConfigRec.PerfilActivo: TClusterConfigPerfil;
begin
  Result := Perfiles[kPerfilActivo];
end;

function TClusterConfigRec.GetPerfil(nombre: string): TClusterConfigPerfil;
var
  aPerfil: TClusterConfigPerfil;
  k: integer;
  buscando: boolean;
begin
  k := 0;
  buscando := True;
  while buscando and (k < perfiles.Count) do
  begin
    aPerfil := perfiles[k];
    if aPerfil.nombrePerfil = nombre then
      buscando := False
    else
      Inc(k);
  end;

  if buscando then
    Result := nil
  else
    Result := aPerfil;

end;

procedure TClusterConfigRec.Save;
var
  OldFileMode: byte;
  fconfig: textfile;
  kPerfil: integer;
  aPerfil: TClusterConfigPerfil;
begin
  OldFileMode := fileMode;
  filemode := 1;
  try
    assignfile(fconfig, archi_Cluster_cfg);
    rewrite(fconfig);
    writeln(fconfig, VERSION_Cluster_CONFIG); // versión del archivo
    writeln(fconfig, kPerfilActivo);
    writeln(fconfig, Perfiles.Count);
    for kPerfil := 0 to Perfiles.Count - 1 do
    begin
      aPerfil := perfiles[kPerfil];
      aPerfil.WriteToText(fconfig);
    end;
    closefile(fconfig);

  finally
    filemode := OldFileMode;
  end;
end;

initialization
  Cluster_cfg := nil;

finalization
  if Cluster_cfg <> nil then
  begin
    Cluster_cfg.Free;
    Cluster_cfg := nil;
  end;
end.
