% GETAOSINTIMESPAN performs high-level queries to retrieve AOs from an LTPDA repository.
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
% DESCRIPTION: GETAOSINTIMESPAN performs high-level queries to retrieve AOs
%              from an LTPDA repository. The AOs for that channel in that time-span
%              are joined together and then split on the requested
%              interval. The resulting AO covers the requested interval,
%              assuming that the repositoy contains a contiguos set of AOs
%              spanning the requested time.
%
% CALL:        b = getAOsInTimeSpan(pl)
%
% INPUTS:      pl - a plist containing parameters as described below
%
% OUTPUTS:     b  - a vector of AOs resulting from the query
%
% PARAMETERS:
%
%     choose from
%              'hostname'       - hostname/IP address of LTPDA Repository
%              'database'       - the name of the database to query
%          or
%              'conn'           - a database connection object
%
%    in addition, we need
%              'binary'         - retrieve binary data (true or false)
%              'channels'       - a cell array of AO names
%              'timespan'       - a timespan object to specify the
%                                 time-interval of interest
%
% The timespan is applied start <= data < end.
%
% OPTIONAL PARAMETERS:
%
%    further restrict the search with the following conditions
%
%               'username'   - specify the username of the person who
%                              submitted the AO
%               'submitted'  - specify the date the AO was submitted
%
% EXAMPLES:
%
% 1) Find all AOs which are called 'ChannelX' submitted after 1st May 2007
%
%    pl = plist('hostname', 'localhost', 'database', 'ltpda_test', ...
%               'channels', {'channelX'}, ...
%               'timespan', timespan('2007-05-01 00:00:00', '3000-01-01 12:34:50', ...
%               );
%
%    a = getAOsInTimeSpan(pl);
%
% 2) Find all AOs for ChannelX and ChannelY on 1st May 2007 submitted by
%    hewitson
%
%    pl = plist('hostname', 'localhost', 'database', 'ltpda_test', ...
%               'channels', {'channelX'}, ...
%               'timespan', timespan('2007-05-01 00:00:00', '2007-05-02 00:00:00', ...
%               'username', 'hewitson');
%
%    a = getAOsInTimeSpan(pl);
%
% VERSION:     $Id: getAOsInTimeSpan.m,v 1.3 2010/01/22 12:46:08 ingo Exp $
%
% HISTORY:     25-02-08 M Hewitson
%                 Creation
%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

function varargout = getAOsInTimeSpan(varargin)

  error('### Obsolete as of LTPDA version 2.2. Replaced my AO model retrieve_in_timespan');
  % Collect input ao's, plist's and ao variable names
  in_names = {};
  for ii = 1:nargin
    in_names{end+1} = inputname(ii);
  end
  [pl, pl_invars] = utils.helper.collect_objects(varargin(:), 'plist', in_names);

  % Process the input plist
  conn     = find(pl, 'conn');
  hostname = find(pl, 'hostname');
  database = find(pl, 'database');
  channels = find(pl, 'channels');
  tspan    = find(pl, 'timespan');
  useBinary = find(pl, 'binary');

  % Check inputs
  if isempty(hostname) || ~ischar(hostname)
    if isempty(conn) || ~isa(conn, 'database')
      error(sprintf('### Plist should contain ''hostname'' and ''database'' parameters,\n or a ''conn'' parameter.'));
    end
  end
  if isempty(database) || ~ischar(database)
    if isempty(conn) || ~isa(conn, 'database')
      error(sprintf('### Plist should contain ''hostname'' and ''database'' parameters,\n or a ''conn'' parameter.'));
    end
  end
  if isempty(channels)
    error('### Plist should contain a ''channels'' parameter.');
  end
  if isempty(tspan) || ~isa(tspan, 'timespan')
    error('### Plist should contain a ''timespan'' parameter.');
  end

  % Check the channels value is a cell
  if ~iscell(channels)
    channels = {channels};
  end

  % Get a connection to the database
  iConnected = 0;
  if ~isa(conn, 'database')
    % then we connect
    try
      conn = utils.mysql.connect(hostname, database);
      iConnected = 1;
    catch
      error('### Failed to connect to server: %s/%s', hostname, database);
    end
  end

  % Collect the data
  try
    aout =  hlq(conn, channels, tspan, useBinary);
  catch
    lasterr
    % Do we need to close database connection?
    if iConnected
      close(conn);
    end
    error('### Error retrieving objects.');
  end

  % Do we need to close database connection?
  if iConnected
    close(conn);
  end

  % set outputs
  varargout{1} = aout;
end

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% A prototype for the kind of high-level query functions we might need
function objsOut = hlq(conn, channels, ts, useBinary)

  % prepare output
  objsOut = [];

  % Loop over the channels
  for j=1:length(channels)

    % this channel
    channel = channels{j};

    % the query
    q =      ['select objmeta.obj_id from objmeta,ao,tsdata ' ...
      'where objmeta.obj_id=ao.obj_id ' ...
      'and ao.data_id=tsdata.id ' ...
      sprintf('and objmeta.name=''%s''', channel) ...
      sprintf('and tsdata.t0+INTERVAL tsdata.nsecs SECOND  >= ''%s''', char(ts.startT)) ...
      sprintf('and tsdata.t0 <= ''%s''', char(ts.endT))];

    % execute query
    info = utils.mysql.dbquery(conn, q);

    % collect objects
    if useBinary
      objs = ltpda_uo.retrieve(conn, 'binary', [info{:}]);
    else
      objs = ltpda_uo.retrieve(conn, [info{:}]);
    end
    
    % join these up
    ojn = join([objs{:}]);

    % split out the bit we want
    os = split(ojn, plist('split_type', 'interval', 'timespan', ts));

    % add to outputs
    objsOut = [objsOut os];
  end % end loop over channels
end

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Returns the default plist
function pl = getDefaultPlist(varargin)

  pl = plist('hostname', 'localhost', ...
    'database', 'ltpda_test',  ...
    'channels', {'chan1', 'chan2'}, ...
    'timespan', timespan('1970-01-01 00:00:00', '2010-10-12 12:45:32') ...
    );
end


