/*
 * 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.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, "    ");
            }
        }
   }
}