001/*
002 *  Copyright (c) 2023-2026, Agents-Flex (fuhai999@gmail.com).
003 *  <p>
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 *  <p>
008 *  http://www.apache.org/licenses/LICENSE-2.0
009 *  <p>
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 */
016package com.agentsflex.core.model.config;
017
018import java.io.Serializable;
019import java.util.*;
020
021public class BaseModelConfig implements Serializable {
022    private static final long serialVersionUID = 1L;
023
024    protected String provider;
025    protected String endpoint;
026    protected String requestPath;
027    protected String model;
028    protected String apiKey;
029
030    protected Map<String, Object> customProperties;
031
032
033    public String getProvider() {
034        return provider;
035    }
036
037    public void setProvider(String provider) {
038        this.provider = provider;
039    }
040
041    public String getEndpoint() {
042        return endpoint;
043    }
044
045    public void setEndpoint(String endpoint) {
046        if (endpoint != null && endpoint.endsWith("/")) {
047            endpoint = endpoint.substring(0, endpoint.length() - 1);
048        }
049        this.endpoint = endpoint;
050    }
051
052    public String getRequestPath() {
053        return requestPath;
054    }
055
056    public void setRequestPath(String requestPath) {
057        if (requestPath != null && !requestPath.startsWith("/")) {
058            requestPath = "/" + requestPath;
059        }
060        this.requestPath = requestPath;
061    }
062
063    public String getModel() {
064        return model;
065    }
066
067    public void setModel(String model) {
068        if (model != null) model = model.trim();
069        this.model = model;
070    }
071
072    public String getApiKey() {
073        return apiKey;
074    }
075
076    public void setApiKey(String apiKey) {
077        this.apiKey = apiKey;
078    }
079
080    // ---------- Custom Properties ----------
081
082    public Map<String, Object> getCustomProperties() {
083        return customProperties == null
084            ? Collections.emptyMap()
085            : Collections.unmodifiableMap(customProperties);
086    }
087
088    public void setCustomProperties(Map<String, Object> customProperties) {
089        this.customProperties = customProperties == null
090            ? null
091            : new HashMap<>(customProperties);
092    }
093
094    public void putCustomProperty(String key, Object value) {
095        if (customProperties == null) {
096            customProperties = new HashMap<>();
097        }
098        customProperties.put(key, value);
099    }
100
101    @SuppressWarnings("unchecked")
102    public <T> T getCustomProperty(String key, Class<T> type) {
103        Object value = customProperties == null ? null : customProperties.get(key);
104        if (value == null) return null;
105        if (type.isInstance(value)) {
106            return type.cast(value);
107        }
108        throw new ClassCastException("Property '" + key + "' is not of type " + type.getSimpleName());
109    }
110
111    public String getCustomPropertyString(String key) {
112        return getCustomProperty(key, String.class);
113    }
114
115    // ---------- Utility: Full URL ----------
116
117    public String getFullUrl() {
118        return (endpoint != null ? endpoint : "") +
119            (requestPath != null ? requestPath : "");
120    }
121
122    // ---------- Object Methods ----------
123
124    @Override
125    public String toString() {
126        return "BaseModelConfig{" +
127            "provider='" + provider + '\'' +
128            ", endpoint='" + endpoint + '\'' +
129            ", requestPath='" + requestPath + '\'' +
130            ", model='" + model + '\'' +
131            ", apiKey='[REDACTED]'" +
132            ", customProperties=" + (customProperties == null ? "null" : customProperties.toString()) +
133            '}';
134    }
135
136    @Override
137    public boolean equals(Object o) {
138        if (this == o) return true;
139        if (o == null || getClass() != o.getClass()) return false;
140        BaseModelConfig that = (BaseModelConfig) o;
141        return Objects.equals(provider, that.provider) &&
142            Objects.equals(endpoint, that.endpoint) &&
143            Objects.equals(requestPath, that.requestPath) &&
144            Objects.equals(model, that.model) &&
145            Objects.equals(apiKey, that.apiKey) &&
146            Objects.equals(customProperties, that.customProperties);
147    }
148
149    @Override
150    public int hashCode() {
151        return Objects.hash(provider, endpoint, requestPath, model, apiKey, customProperties);
152    }
153}