classdef PipelineData < handle & bioinfo.pipeline.internal.VersionMixin
    % Key-Value store for Input & Output data in a pipeline. Default value
    % for any key not in the VariableMap is Incomplete, rather than erroring
    properties(Hidden)
        VariableMap
    end
    
    methods
        
        function obj = PipelineData(dataStruct)
            % PipelineData create pipeline data for variables. If vars is a
            % struct, 
            arguments
                dataStruct(1,1) struct = struct();
            end

            obj.VariableMap = containers.Map('KeyType', 'char', 'ValueType', 'any');
             
            varNames = fieldnames(dataStruct);
            
            for v = 1:numel(varNames)
                obj.insert(varNames{v}, dataStruct.(varNames{v}));
            end

            
        end
        
        function val = value(obj, var)
            arguments
                obj
                var(1,1) string
            end
            
            if obj.VariableMap.isKey(var)
                val = obj.VariableMap(var);
            else
                val = bioinfo.pipeline.datatypes.Incomplete;
            end
        end
        
        function vals = values(obj, varSet)
            arguments
                obj
                varSet string = string.empty(0,1);
            end
            

            if nargin == 1
                vals = values(obj.VariableMap);
            else
                varSet = convertStringsToChars(varSet);
                vals = cell(1,numel(varSet));

                if ischar(varSet)
                    varSet = {varSet};
                end

                for v = 1:numel(varSet)
                    vals{v} = obj.value(varSet{v});
                end
            end
            
        end         
        
        function remove(obj, keySet)
            remove(obj.VariableMap, keySet);
        end
        
        function insert(obj, var, value)
            arguments
                obj
                var(1,:) char
                value
            end
            
            obj.VariableMap(var) = value;
        end
        
        function S = struct(obj, vars)
            arguments
                obj
                vars = obj.VariableMap.keys();
            end

            vars = convertStringsToChars(vars);
            
            S = struct();
            
            for v = 1:numel(vars)
                S.(vars{v}) = obj.value(vars{v});
            end
        end

        function objCopy = copy(obj)
            objCopy = bioinfo.pipeline.internal.PipelineData();
            objCopy.VariableMap = [containers.Map('KeyType', 'char', 'ValueType', 'any'); obj.VariableMap];
        end
    end
end