unit Azure.CognitiveServices.TextAnalytics.JSON;

interface

uses
  System.Generics.Collections,
  System.JSON,
  Azure.CognitiveServices.TextAnalytics.Types;

type

  TAcsTextAnalyticsJSON = class
  private
    class function ToSentimentEnum(const AIdent: string): TAcsTextAnalyticsSentiment;
  public
    class procedure Parse(AValue: TJSONValue; out AData: TAcsTextAnalyticsResponse); overload;
    class procedure Parse(AValue: TJSONObject; out AData: TAcsTextAnalyticsResponseDocument); overload;
    class procedure Parse(AValue: TJSONObject; out AData: TAcsTextAnalyticsConfidenceScores); overload;
    class procedure Parse(AValue: TJSONArray; out AData: TArray<TAcsTextAnalyticsSentence>); overload;
    class procedure Parse(AValue: TJSONObject; out AData: TAcsTextAnalyticsSentence); overload;
    class function ToJSON(const AValue: TAcsTextAnalyticsRequestDocument): TJSONObject; overload;
    class function ToJSON(const AValue: TAcsTextAnalyticsRequest): TJSONObject; overload;
    class function ToJSON(const AValue: TArray<TAcsTextAnalyticsRequestDocument>): TJSONArray; overload;
  end;

implementation

uses
  System.SysUtils, Azure.CognitiveServices.ResourceStrings;

class function TAcsTextAnalyticsJSON.ToJSON(const AValue
  : TAcsTextAnalyticsRequest): TJSONObject;
begin
  Result := TJSONObject.Create;
  Result.AddPair('documents', ToJSON(AValue.Documents));
end;

class procedure TAcsTextAnalyticsJSON.Parse(AValue: TJSONValue;
  out AData: TAcsTextAnalyticsResponse);
var
  LObject: TJSONObject;
  LArray: TJSONArray;
  LIndex: Integer;
begin
  LObject := TJSONObject(AValue);
  LArray := TJSONArray(LObject.GetValue('documents'));
  SetLength(AData.Documents, LArray.Count);
  for LIndex := 0 to LArray.Count - 1 do
    Parse(TJSONObject(LArray[LIndex]), AData.Documents[LIndex]);
end;

class procedure TAcsTextAnalyticsJSON.Parse(AValue: TJSONObject;
  out AData: TAcsTextAnalyticsResponseDocument);
begin
  AData.ID := AValue.GetValue<string>('id');
  AData.Sentiment := ToSentimentEnum(AValue.GetValue<string>('sentiment'));
  Parse(TJSONObject(AValue.GetValue('confidenceScores')), AData.ConfidenceScores);
  Parse(TJSONArray(AValue.GetValue('sentences')), AData.Sentences);
end;

class procedure TAcsTextAnalyticsJSON.Parse(AValue: TJSONObject;
  out AData: TAcsTextAnalyticsConfidenceScores);
begin
  AData.Positive := AValue.GetValue<Double>('positive');
  AData.Neutral := AValue.GetValue<Double>('neutral');
  AData.Negative := AValue.GetValue<Double>('negative');
end;

class procedure TAcsTextAnalyticsJSON.Parse(AValue: TJSONArray;
  out AData: TArray<TAcsTextAnalyticsSentence>);
var
  LIndex: Integer;
begin
  SetLength(AData, AValue.Count);
  for LIndex := 0 to AValue.Count - 1 do
    Parse(TJSONObject(AValue[LIndex]), AData[LIndex]);
end;

class function TAcsTextAnalyticsJSON.ToJSON(const AValue
  : TArray<TAcsTextAnalyticsRequestDocument>): TJSONArray;
var
  LItem: TAcsTextAnalyticsRequestDocument;
begin
  Result := TJSONArray.Create();
  for LItem in AValue do
    Result.Add(ToJSON(LItem));
end;

class function TAcsTextAnalyticsJSON.ToSentimentEnum(
  const AIdent: string): TAcsTextAnalyticsSentiment;
const
  Idents: array [TAcsTextAnalyticsSentiment] of string = ('negative', 'neutral', 'positive', 'mixed');
var
  LEnum: TAcsTextAnalyticsSentiment;
begin
  for LEnum := Low(TAcsTextAnalyticsSentiment) to High(TAcsTextAnalyticsSentiment) do
    if Idents[LEnum] = AIdent then
    begin
      Result := LEnum;
      Exit;
    end;
  raise EArgumentException.Create(StrErrTextSentimentInvalid);
end;

class function TAcsTextAnalyticsJSON.ToJSON(const AValue
  : TAcsTextAnalyticsRequestDocument): TJSONObject;
begin
  Result := TJSONObject.Create;
  Result.AddPair('id', AValue.ID);
  Result.AddPair('language', AValue.Language);
  Result.AddPair('text', AValue.Text);
end;

class procedure TAcsTextAnalyticsJSON.Parse(AValue: TJSONObject;
  out AData: TAcsTextAnalyticsSentence);
begin
  AData.Sentiment := ToSentimentEnum(AValue.GetValue<string>('sentiment'));
  Parse(TJSONObject(AValue.GetValue('confidenceScores')), AData.ConfidenceScores);
  AData.Offset := AValue.GetValue<Integer>('offset');
  AData.Length := AValue.GetValue<Integer>('length');
  AData.Text := AValue.GetValue<string>('text');
end;

end.
