classdef (Abstract) Data < target.internal.IUserTargetClass

    properties (Dependent)
        IsValid (1, 1) logical
    end

    properties (Dependent, Hidden)
        Inner
    end

    properties (Transient, GetAccess = protected, SetAccess = private)
        InnerInstance {mustBeScalarOrEmpty} = target.internal.Data.empty()
    end

    methods (Abstract, Static, Access = protected)

        name = getQualifiedName()

        name = getQualifiedInnerName()
    end

    methods

        function this = Data(value)

            if nargin ~= 1
                error(message("targetframework:MATLAB:NoDefaultConstructor", this.getQualifiedName()));
            end

            this.Inner = value;
        end

        function value = get.Inner(this)
            value = this.InnerInstance;
        end

        function set.Inner(this, value)

            if ~isa(value, this.getQualifiedInnerName())
                throwAsCaller(MException(message("targetframework:MATLAB:InvalidInner", this.getQualifiedName())));
            end

            this.InnerInstance = value;
        end

        function value = get.IsValid(this)
            value = this.InnerInstance.IsValid;
        end
    end

    methods (Hidden, Sealed, Static)

        function loadedObject = loadobj(object) %#ok<STOUT>

            if isa(object, "target.Data")
                error(message("targetframework:MATLAB:NoMATSerialization", object.getQualifiedName()));
            else
                error(message("targetframework:MATLAB:NoMATSerialization", "target"));
            end
        end

        function wrapped = wrapValue(unwrapped)
            wrapped = targetframework.internal.user.commandline.matlab.Helpers.wrapValues(unwrapped);
        end

        function unwrapped = unwrapValue(wrapped, inner)
            unwrapped = targetframework.internal.user.commandline.matlab.Helpers.unwrapValueWithExistingInner(wrapped, inner);
        end
    end

    methods (Sealed)

        function validate(this)

            innerThis = targetframework.internal.user.commandline.matlab.Helpers.unwrapValues(this);
            validate(innerThis);
        end
    end

    methods (Hidden, Sealed)

        function value = gt(this, ~) %#ok<STOUT>
            error(message("targetframework:MATLAB:UnsupportedComparison", ">", this.getQualifiedName()));
        end

        function value = ge(this, ~) %#ok<STOUT>
            error(message("targetframework:MATLAB:UnsupportedComparison", ">=", this.getQualifiedName()));
        end

        function value = lt(this, ~) %#ok<STOUT>
            error(message("targetframework:MATLAB:UnsupportedComparison", "<", this.getQualifiedName()));
        end

        function value = le(this, ~) %#ok<STOUT>
            error(message("targetframework:MATLAB:UnsupportedComparison", "<=", this.getQualifiedName()));
        end

        function varargout = sort(this, varargin)
            [innerThis, varargin{:}] = targetframework.internal.user.commandline.matlab.Helpers.unwrapValues(this, varargin{:});
            [varargout{1:nargout}] = targetframework.internal.model.foundation.ModelHelpers.sort(innerThis, varargin{:});
            [varargout{:}] = targetframework.internal.user.commandline.matlab.Helpers.wrapValues(varargout{:});
        end

        function value = isequal(this, varargin)
            [innerThis, varargin{:}] = targetframework.internal.user.commandline.matlab.Helpers.unwrapValues(this, varargin{:});
            value = targetframework.internal.model.foundation.ModelHelpers.isequal(innerThis, varargin{:});
        end

        function value = isequaln(this, varargin)
            value = isequal(this, varargin{:});
        end

        function hash = keyHash(this)
            innerThis = targetframework.internal.user.commandline.matlab.Helpers.unwrapValues(this);
            hash = targetframework.internal.model.foundation.computeChecksum(innerThis);
        end

        function match = keyMatch(this, that)
            match = isequal(this, that);
        end

        function savedObject = saveobj(this) %#ok<STOUT>
            error(message("targetframework:MATLAB:NoMATSerialization", this.getQualifiedName()));
        end
    end
end

%   Copyright 2021-2022 The MathWorks, Inc.