unit XData.Service.Common;

{$I XData.inc}

{$IFNDEF DELPHIXE3_LVL}
  {$DEFINE CUSTOMDEFAULT}
{$ENDIF}

interface

uses
  Generics.Collections, System.Rtti, System.TypInfo, System.Classes, System.StrUtils,
  XData.Sys.Exceptions;

type
  {$IFDEF CUSTOMDEFAULT}
  XDefaultAttribute = class(TCustomAttribute)
  strict protected
    FValue: Variant;
  public
    property Value: Variant read FValue;
  public
    constructor Create(const DefaultValue: Boolean); overload;
    constructor Create(const DefaultValue: Integer); overload;
    constructor Create(const DefaultValue: Int64); overload;
    constructor Create(const DefaultValue: string); overload;
    constructor Create(const DefaultValue: Double); overload;
  end;
  BaseDefaultAttribute = XDefaultAttribute;
  {$ELSE}
  XDefaultAttribute = class(DefaultAttribute)
  public
    constructor Create(const DefaultValue: Boolean); overload;
  end;
  BaseDefaultAttribute = DefaultAttribute;
  {$ENDIF}

  ServiceContractAttribute = class(TCustomAttribute)
  end;

  ServiceImplementationAttribute = class(TCustomAttribute)
  end;

  HttpMethodAttribute = class(TCustomAttribute)
  public
    function HttpMethod: string; virtual; abstract;
  end;

  HttpGetAttribute = class(HttpMethodAttribute)
  public
    function HttpMethod: string; override;
  end;

  HttpPutAttribute = class(HttpMethodAttribute)
  public
    function HttpMethod: string; override;
  end;

  HttpDeleteAttribute = class(HttpMethodAttribute)
  public
    function HttpMethod: string; override;
  end;

  HttpPostAttribute = class(HttpMethodAttribute)
  public
    function HttpMethod: string; override;
  end;

  HttpPatchAttribute = class(HttpMethodAttribute)
  public
    function HttpMethod: string; override;
  end;

  URIPathSegmentAttribute = class(TCustomAttribute)
  private
    FPath: string;
  public
    constructor Create(const APath: string);
    property Path: string read FPath;
  end;

  URIPathAttribute = URIPathSegmentAttribute;
  RouteAttribute = URIPathAttribute;

  ParamBindingAttribute = class(TCustomAttribute)
  end;

  FromQueryAttribute = class(ParamBindingAttribute)
  end;

  FromBodyAttribute = class(ParamBindingAttribute)
  end;

  FromPathAttribute = class(ParamBindingAttribute)
  end;

  SwaggerExcludeAttribute = class(TCustomAttribute)
  end;

  EXDataServiceException = class(EXDataException);

  EXDataInvalidServiceType = class(EXDataServiceException)
  public
    constructor Create(ATypeInfo: PTypeInfo);
  end;

  EXDataInvalidServiceImplementation = class(EXDataServiceException)
  public
    constructor Create(ATypeInfo: PTypeInfo);
  end;

  EXDataServiceInterfaceWithoutGuid = class(EXDataServiceException)
  public
    constructor Create(ATypeInfo: PTypeInfo);
  end;

  IXDataActionParams = interface
  ['{C03C3F42-9931-470E-9674-2349343CCEC5}']
    function GetValue(const ParamName: string): TValue;
    procedure SetValue(const ParamName: string; const Value: TValue);
    function HasValue(const ParamName: string): boolean;
    function ParamNames: TEnumerable<string>;
  end;

procedure RegisterServiceType(const TypeInfo: Pointer); overload;
procedure RegisterServiceType(const AClass: TClass); overload;

implementation

procedure RegisterServiceType(const TypeInfo: Pointer);
begin
end;

procedure RegisterServiceType(const AClass: TClass); overload;
begin
end;

{ XDefaultAttribute }

constructor XDefaultAttribute.Create(const DefaultValue: Boolean);
begin
  FValue := DefaultValue;
end;

{$IFDEF CUSTOMDEFAULT}
constructor XDefaultAttribute.Create(const DefaultValue: Integer);
begin
  FValue := DefaultValue;
end;

constructor XDefaultAttribute.Create(const DefaultValue: Double);
begin
  FValue := DefaultValue;
end;

constructor XDefaultAttribute.Create(const DefaultValue: string);
begin
  FValue := DefaultValue;
end;

constructor XDefaultAttribute.Create(const DefaultValue: Int64);
begin
  FValue := DefaultValue;
end;
{$ENDIF}

{ EXDataInvalidServiceType }

constructor EXDataInvalidServiceType.Create(ATypeInfo: PTypeInfo);
begin
  inherited CreateFmt('Cannot retrieve service client. Type "%s" is not an interface type.', [GetTypeName(ATypeInfo)]);
end;

{ EXDataServiceInterfaceWithoutGuid }

constructor EXDataServiceInterfaceWithoutGuid.Create(ATypeInfo: PTypeInfo);
begin
  inherited CreateFmt('Cannot retrieve service client. Interface type "%s" does not have a GUID.', [GetTypeName(ATypeInfo)]);
end;

{ HttpGetAttribute }

function HttpGetAttribute.HttpMethod: string;
begin
  Result := 'GET';
end;

{ HttpPutAttribute }

function HttpPutAttribute.HttpMethod: string;
begin
  Result := 'PUT';
end;

{ HttpDeleteAttribute }

function HttpDeleteAttribute.HttpMethod: string;
begin
  Result := 'DELETE';
end;

{ URIPathSegmentAttribute }

constructor URIPathSegmentAttribute.Create(const APath: string);
begin
  FPath := APath;
end;

{ HttpPostAttribute }

function HttpPostAttribute.HttpMethod: string;
begin
  Result := 'POST';
end;

{ EXDataInvalidServiceImplementation }

constructor EXDataInvalidServiceImplementation.Create(ATypeInfo: PTypeInfo);
begin
  inherited CreateFmt('Type "%s" is not a valid service implementation.',
    [GetTypeName(ATypeInfo)]);
end;

{ HttpPatchAttribute }

function HttpPatchAttribute.HttpMethod: string;
begin
  Result := 'PATCH';
end;

end.
