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.thing.java.test;
019
020import com.google.common.collect.ImmutableMap;
021
022import dev.enola.thing.Thing;
023import dev.enola.thing.impl.ImmutableThing;
024import dev.enola.thing.java.TBF;
025
026// TODO Is this really needed?!
027// TODO Generate this, from a model
028public final class TestSomethingTBF implements TBF {
029    // TODO make this package-local, and accessible only via TestSomething.Builder?
030
031    @Override
032    public boolean handles(String typeIRI) {
033        return TestSomething.CLASS_IRI.equals(typeIRI);
034    }
035
036    @Override
037    @SuppressWarnings({"rawtypes", "unchecked"})
038    public Thing.Builder<Thing> create(String typeIRI) {
039        if (!handles(typeIRI)) throw new IllegalArgumentException(typeIRI);
040        return (Thing.Builder) new TestSomethingBuilder();
041    }
042
043    @Override
044    public boolean handles(Class<?> builderInterface) {
045        return builderInterface.equals(TestSomething.Builder.class);
046    }
047
048    @Override
049    @SuppressWarnings("unchecked")
050    public <T extends Thing, B extends Thing.Builder<T>> B create(
051            Class<B> builderInterface, Class<T> thingInterface) {
052        if (!builderInterface.equals(TestSomething.Builder.class)
053                || !thingInterface.equals(TestSomething.class))
054            throw new IllegalArgumentException(builderInterface + ", " + thingInterface);
055        return (B) new TestSomethingBuilder();
056    }
057
058    @Override
059    @SuppressWarnings("unchecked")
060    public <T extends Thing, B extends Thing.Builder<T>> B create(
061            Class<B> builderInterface, Class<T> thingInterface, int expectedSize) {
062        if (!builderInterface.equals(TestSomething.Builder.class)
063                || !thingInterface.equals(TestSomething.class))
064            throw new IllegalArgumentException(builderInterface + ", " + thingInterface);
065        return (B) new TestSomethingBuilder(expectedSize);
066    }
067
068    private static final class TestSomethingBuilder extends ImmutableThing.Builder<TestSomething>
069            implements TestSomething.Builder<TestSomething> {
070
071        private TestSomethingBuilder(int expectedSize) {
072            super(TestSomethingImpl::new, expectedSize);
073            addType(TestSomething.CLASS_IRI);
074        }
075
076        private TestSomethingBuilder() {
077            super(TestSomethingImpl::new);
078            addType(TestSomething.CLASS_IRI);
079        }
080
081        private TestSomethingBuilder(ImmutableThing.Factory factory, TestSomething testSomething) {
082            super(
083                    factory,
084                    testSomething.iri(),
085                    testSomething.properties(),
086                    testSomething.datatypes());
087        }
088
089        @Override
090        public TestSomething.Builder<TestSomething> iri(String iri) {
091            super.iri(iri);
092            return this;
093        }
094    }
095
096    private static final class TestSomethingImpl extends ImmutableThing implements TestSomething {
097        private TestSomethingImpl(
098                String iri,
099                ImmutableMap<String, Object> properties,
100                ImmutableMap<String, String> datatypes) {
101            super(iri, properties, datatypes);
102        }
103
104        @Override
105        public TestSomething.Builder<? extends TestSomething> copy() {
106            return new TestSomethingBuilder(TestSomethingImpl::new, this);
107        }
108    }
109}