/*
 * Copyright 2012-present the original author or authors.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      https://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package org.springframework.boot.context.config;

import java.nio.charset.Charset;

import org.jspecify.annotations.Nullable;

import org.springframework.boot.env.PropertySourceLoader;
import org.springframework.util.StringUtils;

/**
 * A reference expanded from the original {@link ConfigDataLocation} that can ultimately
 * be resolved to one or more {@link StandardConfigDataResource resources}.
 *
 * @author Phillip Webb
 * @author Moritz Halbritter
 */
class StandardConfigDataReference {

	private final ConfigDataLocation configDataLocation;

	private final String resourceLocation;

	private final @Nullable String directory;

	private final @Nullable String profile;

	private final PropertySourceLoader propertySourceLoader;

	private final @Nullable Charset encoding;

	/**
	 * Create a new {@link StandardConfigDataReference} instance.
	 * @param configDataLocation the original location passed to the resolver
	 * @param directory the directory of the resource or {@code null} if the reference is
	 * to a file
	 * @param root the root of the resource location
	 * @param profile the profile being loaded
	 * @param extension the file extension for the resource
	 * @param propertySourceLoader the property source loader that should be used for this
	 * reference
	 * @param encoding the encoding of the resource
	 */
	StandardConfigDataReference(ConfigDataLocation configDataLocation, @Nullable String directory, String root,
			@Nullable String profile, @Nullable String extension, PropertySourceLoader propertySourceLoader,
			@Nullable Charset encoding) {
		this.configDataLocation = configDataLocation;
		String profileSuffix = (StringUtils.hasText(profile)) ? "-" + profile : "";
		this.resourceLocation = root + profileSuffix + ((extension != null) ? "." + extension : "");
		this.directory = directory;
		this.profile = profile;
		this.propertySourceLoader = propertySourceLoader;
		this.encoding = encoding;
	}

	ConfigDataLocation getConfigDataLocation() {
		return this.configDataLocation;
	}

	String getResourceLocation() {
		return this.resourceLocation;
	}

	boolean isMandatoryDirectory() {
		return !this.configDataLocation.isOptional() && this.directory != null;
	}

	@Nullable String getDirectory() {
		return this.directory;
	}

	@Nullable String getProfile() {
		return this.profile;
	}

	@Nullable Charset getEncoding() {
		return this.encoding;
	}

	boolean isSkippable() {
		return this.configDataLocation.isOptional() || this.directory != null || this.profile != null;
	}

	PropertySourceLoader getPropertySourceLoader() {
		return this.propertySourceLoader;
	}

	@Override
	public boolean equals(Object obj) {
		if (this == obj) {
			return true;
		}
		if ((obj == null) || (getClass() != obj.getClass())) {
			return false;
		}
		StandardConfigDataReference other = (StandardConfigDataReference) obj;
		return this.resourceLocation.equals(other.resourceLocation);
	}

	@Override
	public int hashCode() {
		return this.resourceLocation.hashCode();
	}

	@Override
	public String toString() {
		return this.resourceLocation;
	}

}
