/**
 *
 * Copyright (c) 2006-2018, Speedment, Inc. All Rights Reserved.
 *
 * 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:
 *
 * http://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 com.speedment.generator.standard.manager;

import com.speedment.common.codegen.constant.SimpleParameterizedType;
import com.speedment.common.codegen.model.*;
import com.speedment.generator.translator.AbstractEntityAndManagerTranslator;
import com.speedment.runtime.config.Column;
import com.speedment.runtime.config.Table;
import com.speedment.runtime.config.trait.HasEnabled;
import com.speedment.runtime.core.manager.Manager;

import java.util.Arrays;
import java.util.Collections;

import static com.speedment.common.codegen.constant.DefaultAnnotationUsage.OVERRIDE;
import static com.speedment.common.codegen.constant.DefaultType.classOf;
import static com.speedment.common.codegen.constant.DefaultType.list;
import static com.speedment.common.codegen.util.Formatting.indent;
import static com.speedment.common.codegen.util.Formatting.nl;
import com.speedment.runtime.config.identifier.TableIdentifier;
import com.speedment.runtime.config.trait.HasAlias;
import static java.util.Comparator.comparing;
import static java.util.stream.Collectors.joining;
import java.util.stream.Stream;

/**
 *
 * @author Emil Forslund
 * @since 2.3.0
 */
public final class GeneratedManagerTranslator
    extends AbstractEntityAndManagerTranslator<Interface> {

    public GeneratedManagerTranslator(Table table) {
        super(table, Interface::of);
    }

    @Override
    protected Interface makeCodeGenModel(File file) {
        return newBuilder(file, getSupport().generatedManagerName())
            .forEveryTable((intf, table) -> {
                file.add(Import.of(getSupport().entityType()));
                file.add(Import.of(Collections.class).setStaticMember("unmodifiableList").static_());
                file.add(Import.of(Arrays.class).setStaticMember("asList").static_());

                intf.public_()
                    .add(SimpleParameterizedType.create(Manager.class, getSupport().entityType()))
                    .add(
                        Field.of(
                            "IDENTIFIER",
                            SimpleParameterizedType.create(TableIdentifier.class, getSupport().entityType())
                        ).set(Value.ofReference("TableIdentifier.of(" + nl()
                            + indent(
                                Stream.<HasAlias>of(
                                    table.getParentOrThrow().getParentOrThrow(),
                                    table.getParentOrThrow(),
                                    table
                                )
                                    .map((HasAlias hasAlias) -> hasAlias.getJavaName())
                                    .map(s -> "\"" + s + "\"")
                                    .collect(joining("," + nl()))
                            ) + nl() + ")" + nl()
                        ))
                    )
                    .add(Field.of("FIELDS", list(SimpleParameterizedType.create(
                        com.speedment.runtime.field.Field.class,
                        getSupport().entityType())
                    )).set(Value.ofReference("unmodifiableList(asList(" + nl() + indent(
                        table.columns()
                            .sorted(comparing(Column::getOrdinalPosition))
                            .filter(HasEnabled::isEnabled)
                            .map(Column::getJavaName)
                            .map(getSupport().namer()::javaStaticFieldName)
                            .map(field -> getSupport().typeName() + "." + field)
                            .collect(joining("," + nl()))
                    ) + nl() + "))")))
                    .add(Method.of("getEntityClass", classOf(getSupport().entityType()))
                        .default_().add(OVERRIDE)
                        .add("return " + getSupport().entityName() + ".class;")
                    );
            }).build();
    }

    @Override
    protected String getJavadocRepresentText() {
        return "The generated base interface for the manager of every {@link "
            + getSupport().entityType().getTypeName() + "} entity.";
    }

    @Override
    protected String getClassOrInterfaceName() {
        return getSupport().generatedManagerName();
    }

    @Override
    public boolean isInGeneratedPackage() {
        return true;
    }
}

@@ -787,17 +787,271 @@
 n.model.
-*
+Field;%0Aimport com.speedment.common.codegen.model.File;%0Aimport com.speedment.common.codegen.model.Import;%0Aimport com.speedment.common.codegen.model.Interface;%0Aimport com.speedment.common.codegen.model.Method;%0Aimport com.speedment.common.codegen.model.Value
 ;%0Aimport
@@ -1205,24 +1205,140 @@
 nfig.Table;%0A
+import com.speedment.runtime.config.identifier.TableIdentifier;%0Aimport com.speedment.runtime.config.trait.HasAlias;%0A
 import com.s
@@ -1379,16 +1379,67 @@
 nabled;%0A
+import com.speedment.runtime.config.trait.HasName;%0A
 import c
@@ -1536,16 +1536,48 @@
 ections;
+%0Aimport java.util.stream.Stream;
 %0A%0Aimport
@@ -1932,124 +1932,8 @@
 nl;%0A
-import com.speedment.runtime.config.identifier.TableIdentifier;%0Aimport com.speedment.runtime.config.trait.HasAlias;%0A
 impo
@@ -2028,40 +2028,8 @@
 ing;
-%0Aimport java.util.stream.Stream;
 %0A%0A/*
@@ -2465,16 +2465,17 @@
 e) -%3E %7B%0A
+%0A
         
@@ -3099,27 +3099,27 @@
 Value.of
-Reference(%22
+Invocation(
 TableIde
@@ -3130,61 +3130,21 @@
 ier.
-of(%22 + nl()%0A                            + indent(%0A   
+class, %22of%22,%0A
     
@@ -3167,17 +3167,16 @@
         
- 
 Stream.%3C
@@ -3184,28 +3184,24 @@
 asAlias%3Eof(%0A
-    
             
@@ -3289,36 +3289,32 @@
                 
-    
 table.getParentO
@@ -3351,28 +3351,24 @@
             
- 
-   
 table%0A      
@@ -3393,100 +3393,30 @@
     
-    )%0A                                    
+)
 .map(
-(
 Has
-Alias hasAlias) -%3E hasAlias.getJava
+Name::get
 Name
-()
 )%0A  
@@ -3449,37 +3449,26 @@
     
-    
 .map(
-s -%3E %22%5C%22%22 + s + %22%5C%22%22
+Value::ofText
 )%0A  
@@ -3501,90 +3501,29 @@
     
-    .collect(joining(%22,%22 + nl()))%0A                            ) + nl() + %22)%22 + nl(
+.toArray(Value%5B%5D::new
 )%0A  

Fix #652 usedatabaseName instead of javaName in table identifier