001/*
002 * SPDX-License-Identifier: Apache-2.0
003 *
004 * Copyright 2025-2026 The Enola <https://enola.dev> Authors
005 *
006 * Licensed under the Apache License, Version 2.0 (the "License");
007 * you may not use this file except in compliance with the License.
008 * You may obtain a copy of the License at
009 *
010 *     https://www.apache.org/licenses/LICENSE-2.0
011 *
012 * Unless required by applicable law or agreed to in writing, software
013 * distributed under the License is distributed on an "AS IS" BASIS,
014 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
015 * See the License for the specific language governing permissions and
016 * limitations under the License.
017 */
018package dev.enola.common.io.hashbrown;
019
020import io.ipfs.multibase.Multibase;
021import io.ipfs.multihash.Multihash;
022
023import java.util.Objects;
024
025/**
026 * An alternative (wrapper, actually) over {@link io.ipfs.multihash.Multihash} which "remembers" its
027 * encoding base.
028 */
029public final class MultihashWithMultibase {
030    // TODO extends Multihash ?
031
032    private final Multibase.Base multibase;
033    private final Multihash multihash;
034
035    public static MultihashWithMultibase decode(String encoded) {
036        Multibase.Base base;
037        if (encoded.length() == 46 && encoded.startsWith("Qm"))
038            // TODO Base58BTC or Base58Flickr ?
039            base = Multibase.Base.Base58BTC;
040        else base = Multibase.Base.lookup(encoded);
041        return new MultihashWithMultibase(base, Multihash.decode(encoded));
042    }
043
044    private MultihashWithMultibase(Multibase.Base multibase, Multihash decode) {
045        this.multibase = multibase;
046        this.multihash = decode;
047    }
048
049    // TODO Give this method a better name...
050    public MultihashWithMultibase copy(byte[] bytes) {
051        var newMultihash = new Multihash(multihash.getType(), bytes);
052        return new MultihashWithMultibase(multibase, newMultihash);
053    }
054
055    public Multihash multihash() {
056        return multihash;
057    }
058
059    public Multibase.Base multibase() {
060        return multibase;
061    }
062
063    @Override
064    public boolean equals(Object o) {
065        if (!(o instanceof MultihashWithMultibase other)) return false;
066        return multihash.equals(other.multihash) && multibase.equals(other.multibase);
067    }
068
069    @Override
070    public int hashCode() {
071        return Objects.hash(multihash, multibase);
072    }
073
074    @Override
075    public String toString() {
076        return Multihashes.toString(multihash, multibase);
077    }
078}