(*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements. See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership. The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License. You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied. See the License for the
 * specific language governing permissions and limitations
 * under the License.
 *)

unit Thrift.Collections;

interface

uses
  SysUtils, Generics.Collections, Generics.Defaults, Thrift.Utils;

type

{$IF CompilerVersion < 21.0}
  TArray<T> = array of T;
{$IFEND}

  IThriftContainer = interface( ISupportsToString)
    ['{E05C0F9D-A4F5-491D-AADA-C926B4BDB6E4}']
  end;


  IThriftDictionary<TKey,TValue> = interface(IThriftContainer)
    ['{25EDD506-F9D1-4008-A40F-5940364B7E46}']
    function GetEnumerator: TEnumerator<TPair<TKey,TValue>>;

    function GetKeys: TDictionary<TKey,TValue>.TKeyCollection;
    function GetValues: TDictionary<TKey,TValue>.TValueCollection;
    function GetItem(const Key: TKey): TValue;
    procedure SetItem(const Key: TKey; const Value: TValue);
    function GetCount: Integer;

    procedure Add(const Key: TKey; const Value: TValue);
    procedure Remove(const Key: TKey);
{$IF CompilerVersion >= 21.0}
    function ExtractPair(const Key: TKey): TPair<TKey,TValue>;
{$IFEND}
    procedure Clear;
    procedure TrimExcess;
    function TryGetValue(const Key: TKey; out Value: TValue): Boolean;
    procedure AddOrSetValue(const Key: TKey; const Value: TValue);
    function ContainsKey(const Key: TKey): Boolean;
    function ContainsValue(const Value: TValue): Boolean;
    function ToArray: TArray<TPair<TKey,TValue>>;

    property Items[const Key: TKey]: TValue read GetItem write SetItem; default;
    property Count: Integer read GetCount;
    property Keys: TDictionary<TKey,TValue>.TKeyCollection read GetKeys;
    property Values: TDictionary<TKey,TValue>.TValueCollection read GetValues;
  end;

  TThriftDictionaryImpl<TKey,TValue> = class( TInterfacedObject, IThriftDictionary<TKey,TValue>, IThriftContainer, ISupportsToString)
  strict private
    FDictionaly : TDictionary<TKey,TValue>;
  strict protected
    function GetEnumerator: TEnumerator<TPair<TKey,TValue>>;

    function GetKeys: TDictionary<TKey,TValue>.TKeyCollection;
    function GetValues: TDictionary<TKey,TValue>.TValueCollection;
    function GetItem(const Key: TKey): TValue;
    procedure SetItem(const Key: TKey; const Value: TValue);
    function GetCount: Integer;

    procedure Add(const Key: TKey; const Value: TValue);
    procedure Remove(const Key: TKey);
{$IF CompilerVersion >= 21.0}
    function ExtractPair(const Key: TKey): TPair<TKey,TValue>;
{$IFEND}
    procedure Clear;
    procedure TrimExcess;
    function TryGetValue(const Key: TKey; out Value: TValue): Boolean;
    procedure AddOrSetValue(const Key: TKey; const Value: TValue);
    function ContainsKey(const Key: TKey): Boolean;
    function ContainsValue(const Value: TValue): Boolean;
    function ToArray: TArray<TPair<TKey,TValue>>;
    property Items[const Key: TKey]: TValue read GetItem write SetItem; default;
    property Count: Integer read GetCount;
    property Keys: TDictionary<TKey,TValue>.TKeyCollection read GetKeys;
    property Values: TDictionary<TKey,TValue>.TValueCollection read GetValues;
  public
    constructor Create(ACapacity: Integer = 0);
    destructor Destroy; override;
    function ToString : string;  override;
  end;

  IThriftList<T> = interface(IThriftContainer)
    ['{29BEEE31-9CB4-401B-AA04-5148A75F473B}']
    function GetEnumerator: TEnumerator<T>;
    function GetCapacity: Integer;
    procedure SetCapacity(Value: Integer);
    function GetCount: Integer;
    procedure SetCount(Value: Integer);
    function GetItem(Index: Integer): T;
    procedure SetItem(Index: Integer; const Value: T);
    function Add(const Value: T): Integer;
    procedure AddRange(const Values: array of T); overload;
    procedure AddRange(const Collection: IEnumerable<T>); overload;
    procedure AddRange(Collection: TEnumerable<T>); overload;
    procedure Insert(Index: Integer; const Value: T);
    procedure InsertRange(Index: Integer; const Values: array of T); overload;
    procedure InsertRange(Index: Integer; const Collection: IEnumerable<T>); overload;
    procedure InsertRange(Index: Integer; const Collection: TEnumerable<T>); overload;
    function Remove(const Value: T): Integer;
    procedure Delete(Index: Integer);
    procedure DeleteRange(AIndex, ACount: Integer);
    function Extract(const Value: T): T;
{$IF CompilerVersion >= 21.0}
    procedure Exchange(Index1, Index2: Integer);
    procedure Move(CurIndex, NewIndex: Integer);
    function First: T;
    function Last: T;
{$IFEND}
    procedure Clear;
    function Contains(const Value: T): Boolean;
    function IndexOf(const Value: T): Integer;
    function LastIndexOf(const Value: T): Integer;
    procedure Reverse;
    procedure Sort; overload;
    procedure Sort(const AComparer: IComparer<T>); overload;
    function BinarySearch(const Item: T; out Index: Integer): Boolean; overload;
    function BinarySearch(const Item: T; out Index: Integer; const AComparer: IComparer<T>): Boolean; overload;
    procedure TrimExcess;
    function ToArray: TArray<T>;
    property Capacity: Integer read GetCapacity write SetCapacity;
    property Count: Integer read GetCount write SetCount;
    property Items[Index: Integer]: T read GetItem write SetItem; default;
  end;

  TThriftListImpl<T> = class( TInterfacedObject, IThriftList<T>, IThriftContainer, ISupportsToString)
  strict private
    FList : TList<T>;
  strict protected
    function GetEnumerator: TEnumerator<T>;
    function GetCapacity: Integer;
    procedure SetCapacity(Value: Integer);
    function GetCount: Integer;
    procedure SetCount(Value: Integer);
    function GetItem(Index: Integer): T;
    procedure SetItem(Index: Integer; const Value: T);
    function Add(const Value: T): Integer;
    procedure AddRange(const Values: array of T); overload;
    procedure AddRange(const Collection: IEnumerable<T>); overload;
    procedure AddRange(Collection: TEnumerable<T>); overload;
    procedure Insert(Index: Integer; const Value: T);
    procedure InsertRange(Index: Integer; const Values: array of T); overload;
    procedure InsertRange(Index: Integer; const Collection: IEnumerable<T>); overload;
    procedure InsertRange(Index: Integer; const Collection: TEnumerable<T>); overload;
    function Remove(const Value: T): Integer;
    procedure Delete(Index: Integer);
    procedure DeleteRange(AIndex, ACount: Integer);
    function Extract(const Value: T): T;
{$IF CompilerVersion >= 21.0}
    procedure Exchange(Index1, Index2: Integer);
    procedure Move(CurIndex, NewIndex: Integer);
    function First: T;
    function Last: T;
{$IFEND}
    procedure Clear;
    function Contains(const Value: T): Boolean;
    function IndexOf(const Value: T): Integer;
    function LastIndexOf(const Value: T): Integer;
    procedure Reverse;
    procedure Sort; overload;
    procedure Sort(const AComparer: IComparer<T>); overload;
    function BinarySearch(const Item: T; out Index: Integer): Boolean; overload;
    function BinarySearch(const Item: T; out Index: Integer; const AComparer: IComparer<T>): Boolean; overload;
    procedure TrimExcess;
    function ToArray: TArray<T>;
    property Capacity: Integer read GetCapacity write SetCapacity;
    property Count: Integer read GetCount write SetCount;
    property Items[Index: Integer]: T read GetItem write SetItem; default;
  public
    constructor Create;
    destructor Destroy; override;
    function ToString : string;  override;
  end;

  IHashSet<TValue> = interface(IThriftContainer)
    ['{0923A3B5-D4D4-48A8-91AD-40238E2EAD66}']
    function GetEnumerator: TEnumerator<TValue>;
    function GetIsReadOnly: Boolean;
    function GetCount: Integer;
    property Count: Integer read GetCount;
    property IsReadOnly: Boolean read GetIsReadOnly;
    procedure Add( const item: TValue);
    procedure Clear;
    function Contains( const item: TValue): Boolean;
    procedure CopyTo(var A: TArray<TValue>; arrayIndex: Integer);
    function Remove( const item: TValue ): Boolean;
  end;

  THashSetImpl<TValue> = class( TInterfacedObject, IHashSet<TValue>, IThriftContainer, ISupportsToString)
  strict private
    FDictionary : IThriftDictionary<TValue,Integer>;
    FIsReadOnly: Boolean;
  strict protected
    function GetEnumerator: TEnumerator<TValue>;
    function GetIsReadOnly: Boolean;
    function GetCount: Integer;
    property Count: Integer read GetCount;
    property IsReadOnly: Boolean read FIsReadOnly;
    procedure Add( const item: TValue);
    procedure Clear;
    function Contains( const item: TValue): Boolean;
    procedure CopyTo(var A: TArray<TValue>; arrayIndex: Integer);
    function Remove( const item: TValue ): Boolean;
  public
    constructor Create;
    function ToString : string;  override;
  end;

implementation

{ THashSetImpl<TValue> }

procedure THashSetImpl<TValue>.Add( const item: TValue);
begin
  if not FDictionary.ContainsKey(item) then
  begin
    FDictionary.Add( item, 0);
  end;
end;

procedure THashSetImpl<TValue>.Clear;
begin
  FDictionary.Clear;
end;

function THashSetImpl<TValue>.Contains( const item: TValue): Boolean;
begin
  Result := FDictionary.ContainsKey(item);
end;

procedure THashSetImpl<TValue>.CopyTo(var A: TArray<TValue>; arrayIndex: Integer);
var
  i : Integer;
  Enumlator : TEnumerator<TValue>;
begin
  Enumlator := GetEnumerator;
  while Enumlator.MoveNext do
  begin
    A[arrayIndex] := Enumlator.Current;
    Inc(arrayIndex);
  end;
end;

constructor THashSetImpl<TValue>.Create;
begin
  inherited;
  FDictionary := TThriftDictionaryImpl<TValue,Integer>.Create;
end;

function THashSetImpl<TValue>.GetCount: Integer;
begin
  Result := FDictionary.Count;
end;

function THashSetImpl<TValue>.GetEnumerator: TEnumerator<TValue>;
begin
  Result := FDictionary.Keys.GetEnumerator;
end;

function THashSetImpl<TValue>.GetIsReadOnly: Boolean;
begin
  Result := FIsReadOnly;
end;

function THashSetImpl<TValue>.Remove( const item: TValue): Boolean;
begin
  Result := False;
  if FDictionary.ContainsKey( item ) then
  begin
    FDictionary.Remove( item );
    Result := not FDictionary.ContainsKey( item );
  end;
end;

function THashSetImpl<TValue>.ToString : string;
var elm : TValue;
    sb : TThriftStringBuilder;
    first : Boolean;
begin
  sb := TThriftStringBuilder.Create('{');
  try
    first := TRUE;
    for elm in FDictionary.Keys do begin
      if first
      then first := FALSE
      else sb.Append(', ');

      sb.Append( StringUtils<TValue>.ToString(elm));
    end;
    sb.Append('}');
    Result := sb.ToString;
  finally
    sb.Free;
  end;
end;

{ TThriftDictionaryImpl<TKey, TValue> }

procedure TThriftDictionaryImpl<TKey, TValue>.Add(const Key: TKey;
  const Value: TValue);
begin
  FDictionaly.Add( Key, Value);
end;

procedure TThriftDictionaryImpl<TKey, TValue>.AddOrSetValue(const Key: TKey;
  const Value: TValue);
begin
  FDictionaly.AddOrSetValue( Key, Value);
end;

procedure TThriftDictionaryImpl<TKey, TValue>.Clear;
begin
  FDictionaly.Clear;
end;

function TThriftDictionaryImpl<TKey, TValue>.ContainsKey(
  const Key: TKey): Boolean;
begin
  Result := FDictionaly.ContainsKey( Key );
end;

function TThriftDictionaryImpl<TKey, TValue>.ContainsValue(
  const Value: TValue): Boolean;
begin
  Result := FDictionaly.ContainsValue( Value );
end;

constructor TThriftDictionaryImpl<TKey, TValue>.Create(ACapacity: Integer);
begin
  inherited Create;
  FDictionaly := TDictionary<TKey,TValue>.Create( ACapacity );
end;

destructor TThriftDictionaryImpl<TKey, TValue>.Destroy;
begin
  FDictionaly.Free;
  inherited;
end;

{$IF CompilerVersion >= 21.0}
function TThriftDictionaryImpl<TKey, TValue>.ExtractPair( const Key: TKey): TPair<TKey, TValue>;
begin
  Result := FDictionaly.ExtractPair( Key);
end;
{$IFEND}

function TThriftDictionaryImpl<TKey, TValue>.GetCount: Integer;
begin
  Result := FDictionaly.Count;
end;

function TThriftDictionaryImpl<TKey, TValue>.GetEnumerator: TEnumerator<TPair<TKey, TValue>>;
begin
  Result := FDictionaly.GetEnumerator;
end;

function TThriftDictionaryImpl<TKey, TValue>.GetItem(const Key: TKey): TValue;
begin
  Result := FDictionaly.Items[Key];
end;

function TThriftDictionaryImpl<TKey, TValue>.GetKeys: TDictionary<TKey, TValue>.TKeyCollection;
begin
  Result := FDictionaly.Keys;
end;

function TThriftDictionaryImpl<TKey, TValue>.GetValues: TDictionary<TKey, TValue>.TValueCollection;
begin
  Result := FDictionaly.Values;
end;

procedure TThriftDictionaryImpl<TKey, TValue>.Remove(const Key: TKey);
begin
  FDictionaly.Remove( Key );
end;

procedure TThriftDictionaryImpl<TKey, TValue>.SetItem(const Key: TKey;
  const Value: TValue);
begin
  FDictionaly.AddOrSetValue( Key, Value);
end;

function TThriftDictionaryImpl<TKey, TValue>.ToArray: TArray<TPair<TKey, TValue>>;
{$IF CompilerVersion < 22.0}
var
  x : TPair<TKey, TValue>;
  i : Integer;
{$IFEND}
begin
{$IF CompilerVersion < 22.0}
  SetLength(Result, Count);
  i := 0;
  for x in FDictionaly do
  begin
    Result[i] := x;
    Inc( i );
  end;
{$ELSE}
  Result := FDictionaly.ToArray;
{$IFEND}
end;

function TThriftDictionaryImpl<TKey, TValue>.ToString : string;
var pair : TPair<TKey, TValue>;
    sb : TThriftStringBuilder;
    first : Boolean;
begin
  sb := TThriftStringBuilder.Create('{');
  try
    first := TRUE;
    for pair in FDictionaly do begin
      if first
      then first := FALSE
      else sb.Append(', ');

      sb.Append( '(');
      sb.Append( StringUtils<TKey>.ToString(pair.Key));
      sb.Append(' => ');
      sb.Append( StringUtils<TValue>.ToString(pair.Value));
      sb.Append(')');
    end;
    sb.Append('}');
    Result := sb.ToString;
  finally
    sb.Free;
  end;
end;

procedure TThriftDictionaryImpl<TKey, TValue>.TrimExcess;
begin
  FDictionaly.TrimExcess;
end;

function TThriftDictionaryImpl<TKey, TValue>.TryGetValue(const Key: TKey;
  out Value: TValue): Boolean;
begin
  Result := FDictionaly.TryGetValue( Key, Value);
end;

{ TThriftListImpl<T> }

function TThriftListImpl<T>.Add(const Value: T): Integer;
begin
  Result := FList.Add( Value );
end;

procedure TThriftListImpl<T>.AddRange(Collection: TEnumerable<T>);
begin
  FList.AddRange( Collection );
end;

procedure TThriftListImpl<T>.AddRange(const Collection: IEnumerable<T>);
begin
  FList.AddRange( Collection );
end;

procedure TThriftListImpl<T>.AddRange(const Values: array of T);
begin
  FList.AddRange( Values );
end;

function TThriftListImpl<T>.BinarySearch(const Item: T;
  out Index: Integer): Boolean;
begin
  Result := FList.BinarySearch( Item, Index);
end;

function TThriftListImpl<T>.BinarySearch(const Item: T; out Index: Integer;
  const AComparer: IComparer<T>): Boolean;
begin
  Result := FList.BinarySearch( Item, Index, AComparer);
end;

procedure TThriftListImpl<T>.Clear;
begin
  FList.Clear;
end;

function TThriftListImpl<T>.Contains(const Value: T): Boolean;
begin
  Result := FList.Contains( Value );
end;

constructor TThriftListImpl<T>.Create;
begin
  inherited;
  FList := TList<T>.Create;
end;

procedure TThriftListImpl<T>.Delete(Index: Integer);
begin
  FList.Delete( Index )
end;

procedure TThriftListImpl<T>.DeleteRange(AIndex, ACount: Integer);
begin
  FList.DeleteRange( AIndex, ACount)
end;

destructor TThriftListImpl<T>.Destroy;
begin
  FList.Free;
  inherited;
end;

{$IF CompilerVersion >= 21.0}
procedure TThriftListImpl<T>.Exchange(Index1, Index2: Integer);
begin
  FList.Exchange( Index1, Index2 )
end;
{$IFEND}

function TThriftListImpl<T>.Extract(const Value: T): T;
begin
  Result := FList.Extract( Value )
end;

{$IF CompilerVersion >= 21.0}
function TThriftListImpl<T>.First: T;
begin
  Result := FList.First;
end;
{$IFEND}

function TThriftListImpl<T>.GetCapacity: Integer;
begin
  Result := FList.Capacity;
end;

function TThriftListImpl<T>.GetCount: Integer;
begin
  Result := FList.Count;
end;

function TThriftListImpl<T>.GetEnumerator: TEnumerator<T>;
begin
  Result := FList.GetEnumerator;
end;

function TThriftListImpl<T>.GetItem(Index: Integer): T;
begin
  Result := FList[Index];
end;

function TThriftListImpl<T>.IndexOf(const Value: T): Integer;
begin
  Result := FList.IndexOf( Value );
end;

procedure TThriftListImpl<T>.Insert(Index: Integer; const Value: T);
begin
  FList.Insert( Index, Value);
end;

procedure TThriftListImpl<T>.InsertRange(Index: Integer;
  const Collection: TEnumerable<T>);
begin
  FList.InsertRange( Index, Collection );
end;

procedure TThriftListImpl<T>.InsertRange(Index: Integer;
  const Values: array of T);
begin
  FList.InsertRange( Index, Values);
end;

procedure TThriftListImpl<T>.InsertRange(Index: Integer;
  const Collection: IEnumerable<T>);
begin
  FList.InsertRange( Index, Collection );
end;

{$IF CompilerVersion >= 21.0}
function TThriftListImpl<T>.Last: T;
begin
  Result := FList.Last;
end;
{$IFEND}

function TThriftListImpl<T>.LastIndexOf(const Value: T): Integer;
begin
  Result := FList.LastIndexOf( Value );
end;

{$IF CompilerVersion >= 21.0}
procedure TThriftListImpl<T>.Move(CurIndex, NewIndex: Integer);
begin
  FList.Move( CurIndex,  NewIndex);
end;
{$IFEND}

function TThriftListImpl<T>.Remove(const Value: T): Integer;
begin
  Result := FList.Remove( Value );
end;

procedure TThriftListImpl<T>.Reverse;
begin
  FList.Reverse;
end;

procedure TThriftListImpl<T>.SetCapacity(Value: Integer);
begin
  FList.Capacity := Value;
end;

procedure TThriftListImpl<T>.SetCount(Value: Integer);
begin
  FList.Count := Value;
end;

procedure TThriftListImpl<T>.SetItem(Index: Integer; const Value: T);
begin
  FList[Index] := Value;
end;

procedure TThriftListImpl<T>.Sort;
begin
  FList.Sort;
end;

procedure TThriftListImpl<T>.Sort(const AComparer: IComparer<T>);
begin
  FList.Sort(AComparer);
end;

function TThriftListImpl<T>.ToArray: TArray<T>;
{$IF CompilerVersion < 22.0}
var
  x : T;
  i : Integer;
{$IFEND}
begin
{$IF CompilerVersion < 22.0}
  SetLength(Result, Count);
  i := 0;
  for x in FList do
  begin
    Result[i] := x;
    Inc( i );
  end;
{$ELSE}
  Result := FList.ToArray;
{$IFEND}
end;

function TThriftListImpl<T>.ToString : string;
var elm : T;
    sb : TThriftStringBuilder;
    first : Boolean;
begin
  sb := TThriftStringBuilder.Create('{');
  try
    first := TRUE;
    for elm in FList do begin
      if first
      then first := FALSE
      else sb.Append(', ');

      sb.Append( StringUtils<T>.ToString(elm));
    end;
    sb.Append('}');
    Result := sb.ToString;
  finally
    sb.Free;
  end;
end;

procedure TThriftListImpl<T>.TrimExcess;
begin
  FList.TrimExcess;
end;

end.
