program termometerwttr;
{$MODE OBJFPC}{$H+}{$RANGECHECKS ON}

{
    Termometer wttr.in
    For GNU/Linux.
    Version: 2.
    Written on FreePascal (https://freepascal.org/).
    Copyright (C) 2025  Artyomov Alexander
    http://self-made-free.ru/
    aralni@mail.ru

    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU Affero General Public License as
    published by the Free Software Foundation, either version 3 of the
    License, or (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU Affero General Public License for more details.

    You should have received a copy of the GNU Affero General Public License
    along with this program.  If not, see <https://www.gnu.org/licenses/>.
}

uses
  BaseUnix, SysUtils, DateUtils, StrUtils, Math, 
  Unix,Process,classes,fpjson, jsonparser;

{ Обработчик сигнала. Устанавливает флаг timed_out. }
procedure alarm_handler(sig: cint); cdecl;
begin
  // В реальном production-коде не рекомендуется вызывать небезопасные функции внутри обработчика сигнала.
  // Здесь для демонстрации печать допустима, но идеальнее — только атомарные операции/флаги.
//  timed_out := True;
//  writeln('>>> Timer fired (SIGALRM). Флаг timed_out = true');
WriteLn('na');
Halt;
end;

{ C-объявления функций из libc }
function signal(sig: cint; handler: pointer): pointer; cdecl; external 'c' name 'signal';
function alarm(seconds: cint): cint; cdecl; external 'c' name 'alarm';

function Filter(s:string):string;
var f:LongInt;
begin
result := '';
for f := 1 to Length(s) do begin
 case s[f] of
  '0'..'9','-': Result := Result+s[f];
 end;
end;
end;

function GetWeatherInfo(const City: string = ''): string;
var
  Process: TProcess;
  OutputStream: TStream;
  BytesRead: LongInt;
  Buffer: array[1..2048] of byte;
  JsonString: string;
  JsonData: TJSONData;
begin
  Result := 'NO INFO';//'Не удалось получить данные о погоде';
  Process := TProcess.Create(nil);
  try
    Process.Executable := 'curl';
    if City = '' then
      Process.Parameters.Add('https://wttr.in/?format=j1')
    else
      Process.Parameters.Add('https://wttr.in/' + City + '?format=j1');
    
    Process.Options := [poUsePipes];
    Process.Execute;
    
    OutputStream := TMemoryStream.Create;
    try
      while Process.Running or (Process.Output.NumBytesAvailable > 0) do
      begin
        BytesRead := Process.Output.Read(Buffer, SizeOf(Buffer));
        OutputStream.Write(Buffer, BytesRead);
      end;

if OutputStream.Size < 10 then Exit('na');

      SetLength(JsonString, OutputStream.Size);
      OutputStream.Position := 0;
      OutputStream.ReadBuffer(JsonString[1], OutputStream.Size); // если OutputStream.Size = 0 здесь ошибка
      
      try
        JsonData := GetJSON(JsonString);
        try
          Result := {'Текущая погода: ' + }
                    JsonData.FindPath('current_condition[0].temp_C').AsString {+ 'c'} {+ '°C, ' +}
                    {JsonData.FindPath('current_condition[0].weatherDesc[0].value').AsString};
        finally
          JsonData.Free;
        end;
      except
        on E: Exception do begin WriteLn('na'); Halt; end;
//          Result := 'Ошибка обработки данных: ' + E.Message;
      end;
    finally
      OutputStream.Free;
    end;
  finally
    Process.Free;
  end;
Result := Filter(Result);
if Result = '' then WriteLn('na');
end;

var
sity,weather:string;
begin
if ParamCount > 0 then sity := ParamStr(1) else sity := '';

  // Устанавливаем обработчик и запуск таймера
  signal(SIGALRM, @alarm_handler);
  alarm(5); // через 5 секунд придёт SIGALRM

weather := GetWeatherInfo(sity);
WriteLn(weather);
end.