% ------------------------------------------------------------------------------
% Check consistency of PROF an TRAJ_NMEAS structures in terms of PARAM_DATA_MODE
% vs DATA/DATA_ADJUSTED sizes and contents.
%
% SYNTAX :
%  check_prof_and_traj_struct_consistency(a_tabProfiles, a_tabTrajNMeas)
%
% INPUT PARAMETERS :
%   a_tabProfiles   : input profile structures
%   a_tabTrajNMeas  : input trajectory N_MEASUREMENT measurement structures
%
% OUTPUT PARAMETERS :
%
% EXAMPLES :
%
% SEE ALSO :
% AUTHORS  : Jean-Philippe Rannou (Altran)(jean-philippe.rannou@altran.com)
% ------------------------------------------------------------------------------
% RELEASES :
%  01/30/2021 - RNU - creation
% ------------------------------------------------------------------------------
function check_prof_and_traj_struct_consistency(a_tabProfiles, a_tabTrajNMeas)

% current float WMO number
global g_decArgo_floatNum;

fprintf('INFO: PROF-TRAJ CONSISTENCY: Start\n');
tic;

% check consistency of profile data structure
cyNum = -1;
for idProf = 1:length(a_tabProfiles)
   prof = a_tabProfiles(idProf);
   if (prof.outputCycleNumber ~= cyNum)
      nProf = 1;
      cyNum = prof.outputCycleNumber;
   else
      nProf = nProf + 1;
   end
   if (~isempty(prof))
      paramList = prof.paramList;
      paramDataMode = prof.paramDataMode;
      paramNumberWithSubLevels = prof.paramNumberWithSubLevels;
      paramNumberOfSubLevels = prof.paramNumberOfSubLevels;
      data = prof.data;
      dataAdj = prof.dataAdj;
      presOffset = prof.presOffset;
      
      if (~isempty(paramList))
         if (length(paramNumberWithSubLevels) ~= length(paramNumberOfSubLevels))
            fprintf('ERROR: PROF-TRAJ CONSISTENCY: PROF: Float #%d Cycle #%d: nProf %d: length(paramNumberWithSubLevels) and length(paramNumberOfSubLevels) differ\n', ...
               g_decArgo_floatNum, ...
               prof.outputCycleNumber, ...
               nProf);
         end
         if (isempty(paramNumberWithSubLevels))
            if (length(paramList) == size(data, 2))
               
               if (~isempty(paramDataMode))
                  if (length(paramDataMode) == length(paramList))
                     
                     % for pressure offset adjustment
                     if (~isempty(presOffset))
                        if (~isempty(paramDataMode))
                           idPres = find(strcmp({paramList.name}, 'PRES'));
                           if (~isempty(idPres))
                              if (paramDataMode(idPres) ~= 'A')
                                 fprintf('ERROR: PROF-TRAJ CONSISTENCY: PROF: Float #%d Cycle #%d: nProf %d: paramDataMode not ''A'' while presOffset exists\n', ...
                                    g_decArgo_floatNum, ...
                                    prof.outputCycleNumber, ...
                                    nProf);
                              end
                           else
                              fprintf('ERROR: PROF-TRAJ CONSISTENCY: PROF: Float #%d Cycle #%d: nProf %d: no ''PRES'' parameter while presOffset exists\n', ...
                                 g_decArgo_floatNum, ...
                                 prof.outputCycleNumber, ...
                                 nProf);
                           end
                        else
                           fprintf('ERROR: PROF-TRAJ CONSISTENCY: PROF: Float #%d Cycle #%d: nProf %d: paramDataMode empty while presOffset exists\n', ...
                              g_decArgo_floatNum, ...
                              prof.outputCycleNumber, ...
                              nProf);
                        end
                     end
                     
                     if (~all(paramDataMode == ' '))
                        if (~isempty(dataAdj) || (isempty(dataAdj) && (size(dataAdj, 2) > 0)))
                           if (size(dataAdj, 2) == size(data, 2))
                              if (size(dataAdj, 1) == size(data, 1))
                                 
                                 for idParam = 1:length(paramList)
                                    param = paramList(idParam);
                                    paramDataAdj = dataAdj(:, idParam);
                                    if (paramDataMode(idParam) == ' ')
                                       if (any(paramDataAdj ~= param.fillValue))
                                          fprintf('ERROR: PROF-TRAJ CONSISTENCY: PROF: Float #%d Cycle #%d: nProf %d: param ''%s'': paramDataMode = '' '' but dataAdj differ from fillvalue\n', ...
                                             g_decArgo_floatNum, ...
                                             prof.outputCycleNumber, ...
                                             nProf, ...
                                             param.name);
                                       end
                                    else
                                       if (all(paramDataAdj == param.fillValue))
                                          fprintf('ERROR: PROF-TRAJ CONSISTENCY: PROF: Float #%d Cycle #%d: nProf %d: param ''%s'': paramDataMode = ''A'' but all dataAdj equal fillvalue\n', ...
                                             g_decArgo_floatNum, ...
                                             prof.outputCycleNumber, ...
                                             nProf, ...
                                             param.name);
                                       end
                                    end
                                    clear paramDataAdj
                                 end
                                 
                              else
                                 fprintf('ERROR: PROF-TRAJ CONSISTENCY: PROF: Float #%d Cycle #%d: nProf %d: size(data, 1) and size(dataAdj, 1) differ with existing paramDataMode\n', ...
                                    g_decArgo_floatNum, ...
                                    prof.outputCycleNumber, ...
                                    nProf);
                              end
                           else
                              fprintf('ERROR: PROF-TRAJ CONSISTENCY: PROF: Float #%d Cycle #%d: nProf %d: size(data, 2) and size(dataAdj, 2) differ with existing paramDataMode\n', ...
                                 g_decArgo_floatNum, ...
                                 prof.outputCycleNumber, ...
                                 nProf);
                           end
                        else
                           fprintf('ERROR: PROF-TRAJ CONSISTENCY: PROF: Float #%d Cycle #%d: nProf %d: dataAdj empty while paramDataMode exists\n', ...
                              g_decArgo_floatNum, ...
                              prof.outputCycleNumber, ...
                              nProf);
                        end
                     else
                        fprintf('ERROR: PROF-TRAJ CONSISTENCY: PROF: Float #%d Cycle #%d: nProf %d: paramDataMode useless\n', ...
                           g_decArgo_floatNum, ...
                           prof.outputCycleNumber, ...
                           nProf);
                     end
                  else
                     fprintf('ERROR: PROF-TRAJ CONSISTENCY: PROF: Float #%d Cycle #%d: nProf %d: length(paramList) and length(paramDataMode) differ\n', ...
                        g_decArgo_floatNum, ...
                        prof.outputCycleNumber, ...
                        nProf);
                  end
               else
                  if (~isempty(dataAdj))
                     fprintf('ERROR: PROF-TRAJ CONSISTENCY: PROF: Float #%d Cycle #%d: nProf %d: no paramDataMode while dataAdj exists\n', ...
                        g_decArgo_floatNum, ...
                        prof.outputCycleNumber, ...
                        nProf);
                  end
               end
            else
               fprintf('ERROR: PROF-TRAJ CONSISTENCY: PROF: Float #%d Cycle #%d: nProf %d: length(paramList) and length(data) differ\n', ...
                  g_decArgo_floatNum, ...
                  prof.outputCycleNumber, ...
                  nProf);
            end
            
         else
            
            if (length(paramList) == size(data, 2)-sum(paramNumberOfSubLevels)+length(paramNumberOfSubLevels))
               if (~isempty(paramDataMode))
                  if (length(paramDataMode) == length(paramList))
                     
                     % for pressure offset adjustment
                     if (~isempty(presOffset))
                        if (~isempty(paramDataMode))
                           idPres = find(strcmp({paramList.name}, 'PRES'));
                           if (~isempty(idPres))
                              if (paramDataMode(idPres) ~= 'A')
                                 fprintf('ERROR: PROF-TRAJ CONSISTENCY: PROF: Float #%d Cycle #%d: nProf %d: paramDataMode not ''A'' while presOffset exists\n', ...
                                    g_decArgo_floatNum, ...
                                    prof.outputCycleNumber, ...
                                    nProf);
                              end
                           else
                              fprintf('ERROR: PROF-TRAJ CONSISTENCY: PROF: Float #%d Cycle #%d: nProf %d: no ''PRES'' parameter while presOffset exists\n', ...
                                 g_decArgo_floatNum, ...
                                 prof.outputCycleNumber, ...
                                 nProf);
                           end
                        else
                           fprintf('ERROR: PROF-TRAJ CONSISTENCY: PROF: Float #%d Cycle #%d: nProf %d: paramDataMode empty while presOffset exists\n', ...
                              g_decArgo_floatNum, ...
                              prof.outputCycleNumber, ...
                              nProf);
                        end
                     end
                     
                     if (~all(paramDataMode == ' '))
                        if (~isempty(dataAdj) || (isempty(dataAdj) && (size(dataAdj, 2) > 0)))
                           if (size(dataAdj, 2) == size(data, 2))
                              if (size(dataAdj, 1) == size(data, 1))
                                 
                                 cptWithSub = 0;
                                 offset = 0;
                                 for idParam = 1:length(paramList)
                                    param = paramList(idParam);
                                    if (ismember(idParam, paramNumberWithSubLevels))
                                       cptWithSub = cptWithSub + 1;
                                       offset = offset + paramNumberOfSubLevels(cptWithSub) - 1;
                                       continue % no check of spectrum data
                                    end
                                    paramDataAdj = dataAdj(:, idParam+offset);
                                    if (paramDataMode(idParam) == ' ')
                                       if (any(paramDataAdj ~= param.fillValue))
                                          fprintf('ERROR: PROF-TRAJ CONSISTENCY: PROF: Float #%d Cycle #%d: nProf %d: param ''%s'': paramDataMode = '' '' but dataAdj differ from fillvalue\n', ...
                                             g_decArgo_floatNum, ...
                                             prof.outputCycleNumber, ...
                                             nProf, ...
                                             param.name);
                                       end
                                    else
                                       if (all(paramDataAdj == param.fillValue))
                                          fprintf('ERROR: PROF-TRAJ CONSISTENCY: PROF: Float #%d Cycle #%d: nProf %d: param ''%s'': paramDataMode = ''A'' but all dataAdj equal fillvalue\n', ...
                                             g_decArgo_floatNum, ...
                                             prof.outputCycleNumber, ...
                                             nProf, ...
                                             param.name);
                                       end
                                    end
                                    clear paramDataAdj
                                 end
                                 
                              else
                                 fprintf('ERROR: PROF-TRAJ CONSISTENCY: PROF: Float #%d Cycle #%d: nProf %d: size(data, 1) and size(dataAdj, 1) differ with existing paramDataMode\n', ...
                                    g_decArgo_floatNum, ...
                                    prof.outputCycleNumber, ...
                                    nProf);
                              end
                           else
                              fprintf('ERROR: PROF-TRAJ CONSISTENCY: PROF: Float #%d Cycle #%d: nProf %d: size(data, 2) and size(dataAdj, 2) differ with existing paramDataMode\n', ...
                                 g_decArgo_floatNum, ...
                                 prof.outputCycleNumber, ...
                                 nProf);
                           end
                        else
                           fprintf('ERROR: PROF-TRAJ CONSISTENCY: PROF: Float #%d Cycle #%d: nProf %d: dataAdj empty while paramDataMode exists\n', ...
                              g_decArgo_floatNum, ...
                              prof.outputCycleNumber, ...
                              nProf);
                        end
                     else
                        fprintf('ERROR: PROF-TRAJ CONSISTENCY: PROF: Float #%d Cycle #%d: nProf %d: paramDataMode useless\n', ...
                           g_decArgo_floatNum, ...
                           prof.outputCycleNumber, ...
                           nProf);
                     end
                  else
                     fprintf('ERROR: PROF-TRAJ CONSISTENCY: PROF: Float #%d Cycle #%d: nProf %d: length(paramList) and length(paramDataMode) differ\n', ...
                        g_decArgo_floatNum, ...
                        prof.outputCycleNumber, ...
                        nProf);
                  end
               else
                  if (~isempty(dataAdj))
                     fprintf('ERROR: PROF-TRAJ CONSISTENCY: PROF: Float #%d Cycle #%d: nProf %d: no paramDataMode while dataAdj exists\n', ...
                        g_decArgo_floatNum, ...
                        prof.outputCycleNumber, ...
                        nProf);
                  end
               end
            else
               fprintf('ERROR: PROF-TRAJ CONSISTENCY: PROF: Float #%d Cycle #%d: nProf %d: length(paramList) and size(data, 2)-sum(paramNumberOfSubLevels)+length(paramNumberOfSubLevels) differ\n', ...
                  g_decArgo_floatNum, ...
                  prof.outputCycleNumber, ...
                  nProf);
            end
         end
      else
         fprintf('ERROR: PROF-TRAJ CONSISTENCY: PROF: Float #%d Cycle #%d: nProf %d: Empty paramList\n', ...
            g_decArgo_floatNum, ...
            prof.outputCycleNumber, ...
            nProf);
      end
   else
      fprintf('ERROR: PROF-TRAJ CONSISTENCY: PROF: Float #%d: nProf %d: Empty profile\n', ...
         g_decArgo_floatNum, ...
         nProf);
   end
end

% check consistency of traj N_Meas data structure
for idNM = 1:length(a_tabTrajNMeas)
   nMeas = a_tabTrajNMeas(idNM);
   for idM = 1:length(nMeas.tabMeas)
      measStruct = nMeas.tabMeas(idM);
      if (~isempty(measStruct))
         if (~isempty(measStruct.paramList))
            paramList = measStruct.paramList;
            paramDataMode = measStruct.paramDataMode;
            paramNumberWithSubLevels = measStruct.paramNumberWithSubLevels;
            paramNumberOfSubLevels = measStruct.paramNumberOfSubLevels;
            data = measStruct.paramData;
            dataAdj = measStruct.paramDataAdj;
            presOffset = measStruct.presOffset;
            
            if (length(paramNumberWithSubLevels) ~= length(paramNumberOfSubLevels))
               fprintf('ERROR: PROF-TRAJ CONSISTENCY: TRAJ: Float #%d Cycle #%d: MC %d: idM %d: length(paramNumberWithSubLevels) and length(paramNumberOfSubLevels) differ\n', ...
                  g_decArgo_floatNum, ...
                  nMeas.outputCycleNumber, ...
                  measStruct.measCode, ...
                  idM);
            end
            if (isempty(paramNumberWithSubLevels))
               if (length(paramList) == length(data))
                  
                  % for pressure offset adjustment
                  if (~isempty(presOffset))
                     fprintf('ERROR: PROF-TRAJ CONSISTENCY: TRAJ: Float #%d Cycle #%d: MC %d: idM %d: presOffset not empty\n', ...
                        g_decArgo_floatNum, ...
                        nMeas.outputCycleNumber, ...
                        measStruct.measCode, ...
                        idM);
                  end
                  
                  if (~isempty(paramDataMode))
                     if (length(paramDataMode) == length(paramList))
                        if (~all(paramDataMode == ' '))
                           if (~isempty(dataAdj))
                              if (size(dataAdj, 2) == size(data, 2))
                                 if (size(dataAdj, 1) == size(data, 1))
                                    
                                    for idParam = 1:length(paramList)
                                       param = paramList(idParam);
                                       paramDataAdj = dataAdj(:, idParam);
                                       if (paramDataMode(idParam) == ' ')
                                          if (any(paramDataAdj ~= param.fillValue))
                                             fprintf('ERROR: PROF-TRAJ CONSISTENCY: TRAJ: Float #%d Cycle #%d: MC %d: idM %d: param ''%s'': paramDataMode = '' '' but dataAdj differ from fillvalue\n', ...
                                                g_decArgo_floatNum, ...
                                                nMeas.outputCycleNumber, ...
                                                measStruct.measCode, ...
                                                idM, ...
                                                param.name);
                                          end
                                       else
                                          if (all(paramDataAdj == param.fillValue))
                                             fprintf('ERROR: PROF-TRAJ CONSISTENCY: TRAJ: Float #%d Cycle #%d: MC %d: idM %d: param ''%s'': paramDataMode = ''A'' but all dataAdj equal fillvalue\n', ...
                                                g_decArgo_floatNum, ...
                                                nMeas.outputCycleNumber, ...
                                                measStruct.measCode, ...
                                                idM, ...
                                                param.name);
                                          end
                                       end
                                       clear paramDataAdj
                                    end
                                    
                                 else
                                    fprintf('ERROR: PROF-TRAJ CONSISTENCY: TRAJ: Float #%d Cycle #%d: MC %d: idM %d: size(data, 1) and size(dataAdj, 1) differ with existing paramDataMode\n', ...
                                       g_decArgo_floatNum, ...
                                       nMeas.outputCycleNumber, ...
                                       measStruct.measCode, ...
                                       idM);
                                 end
                              else
                                 fprintf('ERROR: PROF-TRAJ CONSISTENCY: TRAJ: Float #%d Cycle #%d: MC %d: idM %d: size(data, 2) and size(dataAdj, 2) differ with existing paramDataMode\n', ...
                                    g_decArgo_floatNum, ...
                                    nMeas.outputCycleNumber, ...
                                    measStruct.measCode, ...
                                    idM);
                              end
                           else
                              fprintf('ERROR: PROF-TRAJ CONSISTENCY: TRAJ: Float #%d Cycle #%d: MC %d: idM %d: dataAdj empty while paramDataMode exists\n', ...
                                 g_decArgo_floatNum, ...
                                 nMeas.outputCycleNumber, ...
                                 measStruct.measCode, ...
                                 idM);
                           end
                        else
                           fprintf('ERROR: PROF-TRAJ CONSISTENCY: TRAJ: Float #%d Cycle #%d: MC %d: idM %d: paramDataMode useless\n', ...
                              g_decArgo_floatNum, ...
                              nMeas.outputCycleNumber, ...
                              measStruct.measCode, ...
                              idM);
                        end
                     else
                        fprintf('ERROR: PROF-TRAJ CONSISTENCY: TRAJ: Float #%d Cycle #%d: MC %d: idM %d: length(paramList) and length(paramDataMode) differ\n', ...
                           g_decArgo_floatNum, ...
                           nMeas.outputCycleNumber, ...
                           measStruct.measCode, ...
                           idM);
                     end
                  else
                     if (~isempty(dataAdj))
                        fprintf('ERROR: PROF-TRAJ CONSISTENCY: TRAJ: Float #%d Cycle #%d: MC %d: idM %d: no paramDataMode while dataAdj exists\n', ...
                           g_decArgo_floatNum, ...
                           nMeas.outputCycleNumber, ...
                           measStruct.measCode, ...
                           idM);
                     end
                  end
               else
                  fprintf('ERROR: PROF-TRAJ CONSISTENCY: TRAJ: Float #%d Cycle #%d: MC %d: idM %d: length(paramList) and length(data) differ\n', ...
                     g_decArgo_floatNum, ...
                     nMeas.outputCycleNumber, ...
                     measStruct.measCode, ...
                     idM);
               end
            else
               if (length(paramList) == length(data)-sum(paramNumberOfSubLevels)+length(paramNumberOfSubLevels))
                  
                  % for pressure offset adjustment
                  if (~isempty(presOffset))
                     fprintf('ERROR: PROF-TRAJ CONSISTENCY: TRAJ: Float #%d Cycle #%d: MC %d: idM %d: presOffset not empty\n', ...
                        g_decArgo_floatNum, ...
                        nMeas.outputCycleNumber, ...
                        measStruct.measCode, ...
                        idM);
                  end
                  
                  if (~isempty(paramDataMode))
                     if (length(paramDataMode) == length(paramList))
                        if (~all(paramDataMode == ' '))
                           if (~isempty(dataAdj))
                              if (size(dataAdj, 2) == size(data, 2))
                                 if (size(dataAdj, 1) == size(data, 1))
                                    
                                    cptWithSub = 0;
                                    offset = 0;
                                    for idParam = 1:length(paramList)
                                       param = paramList(idParam);
                                       if (ismember(idParam, paramNumberWithSubLevels))
                                          cptWithSub = cptWithSub + 1;
                                          offset = offset + paramNumberOfSubLevels(cptWithSub) - 1;
                                          continue % no check of spectrum data
                                       end
                                       paramDataAdj = dataAdj(:, idParam+offset);
                                       if (paramDataMode(idParam) == ' ')
                                          if (any(paramDataAdj ~= param.fillValue))
                                             fprintf('ERROR: PROF-TRAJ CONSISTENCY: TRAJ: Float #%d Cycle #%d: MC %d: idM %d: param ''%s'': paramDataMode = '' '' but dataAdj differ from fillvalue\n', ...
                                                g_decArgo_floatNum, ...
                                                nMeas.outputCycleNumber, ...
                                                measStruct.measCode, ...
                                                idM, ...
                                                param.name);
                                          end
                                       else
                                          if (all(paramDataAdj == param.fillValue))
                                             fprintf('ERROR: PROF-TRAJ CONSISTENCY: TRAJ: Float #%d Cycle #%d: MC %d: idM %d: param ''%s'': paramDataMode = ''A'' but all dataAdj equal fillvalue\n', ...
                                                g_decArgo_floatNum, ...
                                                nMeas.outputCycleNumber, ...
                                                measStruct.measCode, ...
                                                idM, ...
                                                param.name);
                                          end
                                       end
                                       clear paramDataAdj
                                    end
                                    
                                 else
                                    fprintf('ERROR: PROF-TRAJ CONSISTENCY: TRAJ: Float #%d Cycle #%d: MC %d: idM %d: size(data, 1) and size(dataAdj, 1) differ with existing paramDataMode\n', ...
                                       g_decArgo_floatNum, ...
                                       nMeas.outputCycleNumber, ...
                                       measStruct.measCode, ...
                                       idM);
                                 end
                              else
                                 fprintf('ERROR: PROF-TRAJ CONSISTENCY: TRAJ: Float #%d Cycle #%d: MC %d: idM %d: size(data, 2) and size(dataAdj, 2) differ with existing paramDataMode\n', ...
                                    g_decArgo_floatNum, ...
                                    nMeas.outputCycleNumber, ...
                                    measStruct.measCode, ...
                                    idM);
                              end
                           else
                              fprintf('ERROR: PROF-TRAJ CONSISTENCY: TRAJ: Float #%d Cycle #%d: MC %d: idM %d: dataAdj empty while paramDataMode exists\n', ...
                                 g_decArgo_floatNum, ...
                                 nMeas.outputCycleNumber, ...
                                 measStruct.measCode, ...
                                 idM);
                           end
                        else
                           fprintf('ERROR: PROF-TRAJ CONSISTENCY: TRAJ: Float #%d Cycle #%d: MC %d: idM %d: paramDataMode useless\n', ...
                              g_decArgo_floatNum, ...
                              nMeas.outputCycleNumber, ...
                              measStruct.measCode, ...
                              idM);
                        end
                     else
                        fprintf('ERROR: PROF-TRAJ CONSISTENCY: TRAJ: Float #%d Cycle #%d: MC %d: idM %d: length(paramList) and length(paramDataMode) differ\n', ...
                           g_decArgo_floatNum, ...
                           nMeas.outputCycleNumber, ...
                           measStruct.measCode, ...
                           idM);
                     end
                  else
                     if (~isempty(dataAdj))
                        fprintf('ERROR: PROF-TRAJ CONSISTENCY: TRAJ: Float #%d Cycle #%d: MC %d: idM %d: no paramDataMode while dataAdj exists\n', ...
                           g_decArgo_floatNum, ...
                           nMeas.outputCycleNumber, ...
                           measStruct.measCode, ...
                           idM);
                     end
                  end
               else
                  fprintf('ERROR: PROF-TRAJ CONSISTENCY: TRAJ: Float #%d Cycle #%d: MC %d: idM %d: length(paramList) and length(data)-sum(paramNumberOfSubLevels)+length(paramNumberOfSubLevels) differ\n', ...
                     g_decArgo_floatNum, ...
                     nMeas.outputCycleNumber, ...
                     measStruct.measCode, ...
                     idM);
               end
            end
         end
      else
         fprintf('ERROR: PROF-TRAJ CONSISTENCY: TRAJ: Float #%d: Empty measStruct\n', ...
            g_decArgo_floatNum);
      end
   end
end

ellapsedTime = toc;
fprintf('INFO: PROF-TRAJ CONSISTENCY: Elapsed time is %.1f seconds\n', ellapsedTime);

return
