001/*
002 * Copyright 2022-2026 Revetware LLC.
003 *
004 * Licensed under the Apache License, Version 2.0 (the "License");
005 * you may not use this file except in compliance with the License.
006 * You may obtain a copy of the License at
007 *
008 * http://www.apache.org/licenses/LICENSE-2.0
009 *
010 * Unless required by applicable law or agreed to in writing, software
011 * distributed under the License is distributed on an "AS IS" BASIS,
012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013 * See the License for the specific language governing permissions and
014 * limitations under the License.
015 */
016
017package com.soklet;
018
019import org.jspecify.annotations.NonNull;
020import org.jspecify.annotations.Nullable;
021
022import javax.annotation.concurrent.Immutable;
023
024import static java.util.Objects.requireNonNull;
025
026/**
027 * Resource-list entry exposed by v1 MCP endpoints.
028 *
029 * @author <a href="https://www.revetkn.com">Mark Allen</a>
030 */
031@Immutable
032public record McpListedResource(
033                @NonNull String uri,
034                @NonNull String name,
035                @NonNull String mimeType,
036                @Nullable String title,
037                @Nullable String description,
038                @Nullable Long sizeBytes
039) {
040        public McpListedResource {
041                requireNonNull(uri);
042                requireNonNull(name);
043                requireNonNull(mimeType);
044
045                if (sizeBytes != null && sizeBytes < 0L)
046                        throw new IllegalArgumentException("Resource size metadata must be non-negative.");
047        }
048
049        /**
050         * Creates a minimal resource-list entry without optional metadata.
051         *
052         * @param uri the resource URI
053         * @param name the resource name
054         * @param mimeType the resource MIME type
055         * @return a minimal listed-resource entry
056         */
057        @NonNull
058        public static McpListedResource fromComponents(@NonNull String uri,
059                                                                                                                                                                                                 @NonNull String name,
060                                                                                                                                                                                                 @NonNull String mimeType) {
061                requireNonNull(uri);
062                requireNonNull(name);
063                requireNonNull(mimeType);
064                return new McpListedResource(uri, name, mimeType, null, null, null);
065        }
066
067        /**
068         * Returns a copy of this resource entry with a title.
069         *
070         * @param title the title to apply
071         * @return a new resource entry with the given title
072         */
073        @NonNull
074        public McpListedResource withTitle(@NonNull String title) {
075                requireNonNull(title);
076                return new McpListedResource(uri(), name(), mimeType(), title, description(), sizeBytes());
077        }
078
079        /**
080         * Returns a copy of this resource entry with a description.
081         *
082         * @param description the description to apply
083         * @return a new resource entry with the given description
084         */
085        @NonNull
086        public McpListedResource withDescription(@NonNull String description) {
087                requireNonNull(description);
088                return new McpListedResource(uri(), name(), mimeType(), title(), description, sizeBytes());
089        }
090
091        /**
092         * Returns a copy of this resource entry with a size metadata value.
093         *
094         * @param sizeBytes the non-negative size in bytes
095         * @return a new resource entry with the given size
096         */
097        @NonNull
098        public McpListedResource withSizeBytes(@NonNull Long sizeBytes) {
099                requireNonNull(sizeBytes);
100                return new McpListedResource(uri(), name(), mimeType(), title(), description(), sizeBytes);
101        }
102}