/*
 *  Copyright 2021 konso.
 *
 *  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 org.teavm.backend.c.generate;

import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import org.teavm.model.ValueType;

public class ShorteningFileNameProvider implements FileNameProvider {
    private final FileNameProvider nameProvider;
    private final Map<String, String> names = new HashMap<>();
    private final Set<String> usedNames = new HashSet<>();

    public ShorteningFileNameProvider(FileNameProvider nameProvider) {
        this.nameProvider = nameProvider;
    }

    @Override
    public String fileName(String className) {
        return unique(shorten(nameProvider.fileName(className)));
    }

    @Override
    public String fileName(ValueType type) {
        return unique(shorten(nameProvider.fileName(type)));
    }

    @Override
    public String escapeName(String name) {
        return unique(shorten(nameProvider.escapeName(name)));
    }

    private String unique(String name) {
        return names.computeIfAbsent(name, n -> {
            if (usedNames.add(n)) {
                return n;
            }
            int suffix = 1;
            while (true) {
                String candidate = n + "_" + suffix++;
                if (usedNames.add(candidate)) {
                    return candidate;
                }
            }
        });
    }

    private static String shorten(String name) {
        StringBuilder sb = new StringBuilder();
        int index = 0;
        while (true) {
            int next = name.indexOf('/', index);
            if (next < 0) {
                break;
            }
            if (next > index) {
                sb.append(name.charAt(index));
            }
            sb.append('/');
            index = next + 1;
        }
        return sb.append(name, index, name.length()).toString();
    }
}

@@ -1198,38 +1198,31 @@
      return 
-unique(shorten
+process
 (nameProvide
@@ -1239,25 +1239,24 @@
 (className))
-)
 ;%0A    %7D%0A%0A   
@@ -1322,38 +1322,31 @@
      return 
-unique(shorten
+process
 (nameProvide
@@ -1362,17 +1362,16 @@
 e(type))
-)
 ;%0A    %7D%0A
@@ -1448,22 +1448,15 @@
 urn 
-unique(shorten
+process
 (nam
@@ -1482,17 +1482,16 @@
 e(name))
-)
 ;%0A    %7D%0A
@@ -1514,14 +1514,15 @@
 ing 
-unique
+process
 (Str
@@ -1581,22 +1581,85 @@
 e, n -%3E 
-%7B%0A    
+unique(shorten(n)));%0A    %7D%0A%0A    private String unique(String name) %7B%0A
         
@@ -1677,25 +1677,24 @@
 es.add(n
+ame
 )) %7B%0A
-    
         
@@ -1705,22 +1705,21 @@
 return n
-;%0A    
+ame;%0A
         
@@ -1712,36 +1712,32 @@
 name;%0A        %7D%0A
-    
         int suff
@@ -1748,28 +1748,24 @@
  1;%0A        
-    
 while (true)
@@ -1759,36 +1759,32 @@
  while (true) %7B%0A
-    
             Stri
@@ -1799,16 +1799,19 @@
 date = n
+ame
  + %22_%22 +
@@ -1821,20 +1821,16 @@
 ffix++;%0A
-    
         
@@ -1861,28 +1861,24 @@
 ndidate)) %7B%0A
-    
             
@@ -1903,26 +1903,8 @@
 te;%0A
-                %7D%0A
     
@@ -1922,18 +1922,16 @@
        %7D
-);
 %0A    %7D%0A%0A

fix overlapping file names