/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you 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.apache.sling.serviceusermapping.impl;

import java.io.IOException;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.SortedMap;
import java.util.TreeMap;

import org.apache.felix.inventory.Format;
import org.apache.felix.inventory.InventoryPrinter;
import org.apache.felix.utils.json.JSONWriter;
import org.apache.sling.serviceusermapping.Mapping;
import org.osgi.service.component.annotations.Component;
import org.osgi.service.component.annotations.Reference;

/** InventoryPrinter for service user mappings */
@Component(service = InventoryPrinter.class,
           property = {
                   InventoryPrinter.FORMAT + "=JSON",
                   InventoryPrinter.FORMAT + "=TEXT",
                   InventoryPrinter.TITLE + "=Sling Service User Mappings",
                   InventoryPrinter.WEBCONSOLE + ":Boolean=true"
           })
public class MappingInventoryPrinter implements InventoryPrinter {

    @Reference
    private ServiceUserMapperImpl mapper;

    @Override
    public void print(PrintWriter out, Format format, boolean isZip) {
        try {
            if(format.equals(Format.JSON)) {
                renderJson(out);
            } else if(format.equals(Format.TEXT)) {
                renderText(out);
            }
        } catch(Exception e) {
            e.printStackTrace(out);
        }
    }

    private String getMappedUser(Mapping m) {
        return m.map(m.getServiceName(), m.getSubServiceName());
    }

    private String[] getMappedPrincipalNames(Mapping m) {
        Iterable<String> principalNames = m.mapPrincipals(m.getServiceName(), m.getSubServiceName());
        if (principalNames == null) {
            return null;
        } else {
            List<String> l = new ArrayList<>();
            for (String pName : principalNames) {
                l.add(pName);
            }
            return l.toArray(new String[l.size()]);
        }
    }

    private SortedMap<String, List<Mapping>> getMappingsByUser(List<Mapping> mappings) {
        SortedMap<String, List<Mapping>> result = new TreeMap<String, List<Mapping>>();
        for(Mapping m : mappings) {
            final String user = getMappedUser(m);
            if (user != null) {
                List<Mapping> list = result.get(user);
                if (list == null) {
                    list = new ArrayList<Mapping>();
                    result.put(user, list);
                }
                list.add(m);
            }
        }
        return result;
    }

    private SortedMap<String, List<Mapping>> getMappingsByPrincipalName(List<Mapping> mappings) {
        SortedMap<String, List<Mapping>> result = new TreeMap<String, List<Mapping>>();
        for(Mapping m : mappings) {
            final String[] principalNames = getMappedPrincipalNames(m);
            if (principalNames != null) {
                for (String pName : principalNames) {
                    List<Mapping> list = result.get(pName);
                    if (list == null) {
                        list = new ArrayList<Mapping>();
                        result.put(pName, list);
                    }
                    list.add(m);
                }
            }
        }
        return result;
    }

    private void asJSON(JSONWriter w, Mapping m) throws IOException {
        w.object();
        w.key("serviceName").value(m.getServiceName());
        w.key("subServiceName").value(m.getSubServiceName());
        String[] pNames = getMappedPrincipalNames(m);
        if (pNames != null) {
            w.key("principals").value(pNames);
        } else {
            w.key("user").value(getMappedUser(m));
        }
        w.endObject();
    }

    private void renderJson(PrintWriter out) throws IOException {
        final List<Mapping> data = mapper.getActiveMappings();
        final Map<String, List<Mapping>> byUser = getMappingsByUser(data);
        final Map<String, List<Mapping>> byPrincipalName = getMappingsByPrincipalName(data);

        final JSONWriter w = new JSONWriter(out);
        w.object();
        w.key("title").value("Service User Mappings");
        w.key("mappingsCount").value(data.size());
        w.key("uniqueUsersCount").value(byUser.keySet().size());
        w.key("uniquePrincipalsCount").value(byPrincipalName.keySet().size());

        w.key("mappingsByUser");
        w.object();
        for(Map.Entry<String, List<Mapping>> e : byUser.entrySet()) {
            w.key(e.getKey());
            w.array();
            for(Mapping m : e.getValue()) {
                asJSON(w,m);
            }
            w.endArray();
        }
        w.endObject();

        w.key("mappingsByPrincipal");
        w.object();
        for(Map.Entry<String, List<Mapping>> e : byPrincipalName.entrySet()) {
            w.key(e.getKey());
            w.array();
            for(Mapping m : e.getValue()) {
                asJSON(w,m);
            }
            w.endArray();
        }
        w.endObject();

        w.endObject();
    }

    private void asText(PrintWriter w, Mapping m, String indent) {
        final String SEP = " / ";
        w.print(indent);
        w.print(m.getServiceName());
        w.print(SEP);
        final String sub = m.getSubServiceName();
        w.print(sub == null ? "" : sub);
        w.print(SEP);
        String[] principalNames = getMappedPrincipalNames(m);
        if (principalNames != null) {
            w.println(Arrays.toString(principalNames));
        } else {
            w.println(getMappedUser(m));
        }
    }

    private void renderText(PrintWriter out) {
        final List<Mapping> data = mapper.getActiveMappings();

        final Map<String, List<Mapping>> byUser = getMappingsByUser(data);

        out.print("*** Mappings by user (");
        out.print(byUser.keySet().size());
        out.print(" users):");
        out.println(" (format: service name / sub service name / user)");

        for(Map.Entry<String, List<Mapping>> e : byUser.entrySet()) {
            out.print("  ");
            out.println(e.getKey());
            for(Mapping m : e.getValue()) {
                asText(out, m, "    ");
            }
        }

        final Map<String, List<Mapping>> byPrincipalName = getMappingsByPrincipalName(data);

        out.print("*** Mappings by principals (");
        out.print(byPrincipalName.keySet().size());
        out.print(" principals):");
        out.println(" (format: service name / sub service name / principal names)");

        for(Map.Entry<String, List<Mapping>> e : byPrincipalName.entrySet()) {
            out.print("  ");
            out.println(e.getKey());
            for(Mapping m : e.getValue()) {
                asText(out, m, "    ");
            }
        }
   }
}