/*--------------------------------------------------------------*/
/* 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.corehunter;

import java.io.IOException;
import java.nio.file.Paths;
import java.util.Arrays;
import org.corehunter.data.CoreHunterData;
import org.corehunter.data.DistanceMatrixData;
import org.corehunter.data.GenotypeData;
import org.corehunter.data.GenotypeDataFormat;
import org.corehunter.data.simple.SimpleDistanceMatrixData;
import org.corehunter.data.simple.SimpleGenotypeData;
import org.corehunter.listener.SimpleCorehunterListener;
import org.jamesframework.core.subset.SubsetSolution;
import uno.informatics.data.Data;
import uno.informatics.data.SimpleEntity;
import uno.informatics.data.dataset.FeatureData;
import uno.informatics.data.feature.array.ArrayFeatureData;
import uno.informatics.data.io.FileType;
import uno.informatics.data.pojo.DataPojo;
import uno.informatics.data.pojo.SimpleEntityPojo;

/**
 * Simple API used by the R interface.
 *
 * @author Herman De Beukelaer, Guy Davenport
 */
public class API {

    /* -------- */
    /* All data */
    /* -------- */
    
    public static String[] getIds(Data data){
        int n = data.getSize();
        String[] ids = new String[n];
        for(int i = 0; i < n; i++){
            ids[i] = data.getHeader(i).getUniqueIdentifier();
        }
        return ids;
    }
    
    public static String[] getIdsFromIndices(Data data, int[] indices){
        String[] ids = Arrays.stream(indices)
                             .mapToObj(i -> data.getHeader(i).getUniqueIdentifier())
                             .toArray(n -> new String[n]);
        return ids;
    }
    
    public static int[] getIndicesFromIds(DataPojo data, String[] ids){
        int[] indices = Arrays.stream(ids)
                              .mapToInt(id -> data.indexOf(id))
                              .toArray();
        return indices;
    }
    
    /* -------------------- */
    /* Distance matrix data */
    /* -------------------- */
    
    public static DistanceMatrixData readDistanceMatrixData(String file) throws IOException{
        return SimpleDistanceMatrixData.readData(Paths.get(file), inferFileType(file));
    }
    
    public static DistanceMatrixData createDistanceMatrixData(double[][] distances, String[] ids, String[] names){
        // combine ids and names into headers
        int n = distances.length;
        if(ids == null){
            throw new IllegalArgumentException("Ids are required.");
        }
        if(ids.length != n){
            throw new IllegalArgumentException("Number of ids does not correspond to size of matrix.");
        }
        if(names == null){
            // use ids as names if no names are given
            names = ids;
        }
        if(names.length != n){
            throw new IllegalArgumentException("Number of names does not correspond to size of matrix.");
        }
        SimpleEntity[] headers = new SimpleEntity[n];
        for(int i = 0; i < n; i++){
            headers[i] = new SimpleEntityPojo(ids[i], names[i]);
        }
        // create and return data
        return new SimpleDistanceMatrixData(headers, distances);
    }
    
    /* ------------- */
    /* Genotype data */
    /* ------------- */
    
    public static GenotypeData readGenotypeData(String file, String format) throws IOException{
        return SimpleGenotypeData.readData(
                Paths.get(file),
                inferFileType(file),
                GenotypeDataFormat.valueOf(format.toUpperCase())
        );
    }
    
    /* -------------- */
    /* Phenotype data */
    /* -------------- */
    
    public static FeatureData readPhenotypeData(String file) throws IOException{
        return ArrayFeatureData.readData(Paths.get(file), inferFileType(file));
    }
    
    /**
     * Get a copy of the full distance matrix.
     * 
     * @param data distance data
     * @return full distance matrix (copy)
     */
    public static double[][] getDistanceMatrix(DistanceMatrixData data){
        int n = data.getSize();
        double[][] dist = new double[n][n];
        for(int i = 0; i < n; i++){
            for (int j = 0; j < n; j++) {
                dist[i][j] = data.getDistance(i, j);
            }
        }
        return dist;
    }
    
    /* --------- */
    /* Arguments */
    /* --------- */
    
    public static CoreHunterObjective createObjective(String type, String measure, double weight){        
        return new CoreHunterObjective(
                CoreHunterObjectiveType.createFromAbbreviation(type),
                CoreHunterMeasure.createFromAbbreviation(measure),
                weight
        );
    }
    
    public static CoreHunterArguments createArguments(CoreHunterData data, int size, CoreHunterObjective[] objectives){
        return new CoreHunterArguments(data, size, Arrays.asList(objectives));
    }
    
    /* --------- */
    /* Execution */
    /* --------- */
    
    public static int[] sampleCore(CoreHunterArguments args, String mode,
                                   int timeLimit, int maxTimeWithoutImprovement,
                                   boolean silent){
        // interpret arguments
        CoreHunterExecutionMode exMode = CoreHunterExecutionMode.DEFAULT;
        if(mode.equals("fast")){
            exMode = CoreHunterExecutionMode.FAST;
        }
        // create Core Hunter executor
        CoreHunter ch = new CoreHunter(exMode);
        if(timeLimit > 0){
            ch.setTimeLimit(timeLimit);
        }
        if(maxTimeWithoutImprovement > 0){
            ch.setMaxTimeWithoutImprovement(maxTimeWithoutImprovement);
        }
        if(!silent){
            ch.setListener(new SimpleCorehunterListener());
        }
        // sample core
        SubsetSolution core = ch.execute(args);
        // convert result
        int[] ids = new int[core.getNumSelectedIDs()];
        int i = 0;
        for(int id : core.getSelectedIDs()){
            ids[i++] = id;
        }
        return ids;
    }
    
    /* ---------- */
    /* Evaluation */
    /* ---------- */
    
    public static double evaluateCore(int[] selected, CoreHunterData data, CoreHunterObjective obj){
        CoreHunter ch = new CoreHunter();
        SubsetSolution sol = new SubsetSolution(data.getIDs());
        for(int sel : selected){
            sol.select(sel);
        }
        return ch.evaluate(sol, data, obj);
    }
        
    /* ----------------------- */
    /* Private utility methods */
    /* ----------------------- */
    
    /**
     * Infer file type from the extension of the file.
     * Only supports {@link FileType#TXT} and {@link FileType#CSV} and returns <code>null</code> for other extensions.
     * 
     * @param file file path
     * @return file type
     */
    private static FileType inferFileType(String file){
        file = file.toLowerCase();
        if(file.endsWith(".txt")){
            return FileType.TXT;
        }
        if(file.endsWith(".csv")){
            return FileType.CSV;
        }
        return null;
    }
    
}

@@ -4912,491 +4912,8 @@
    %0A
-    /**%0A     * Get a copy of the full distance matrix.%0A     * %0A     * @param data distance data%0A     * @return full distance matrix (copy)%0A     */%0A    public static double%5B%5D%5B%5D getDistanceMatrix(DistanceMatrixData data)%7B%0A        int n = data.getSize();%0A        double%5B%5D%5B%5D dist = new double%5Bn%5D%5Bn%5D;%0A        for(int i = 0; i %3C n; i++)%7B%0A            for (int j = 0; j %3C n; j++) %7B%0A                dist%5Bi%5D%5Bj%5D = data.getDistance(i, j);%0A            %7D%0A        %7D%0A        return dist;%0A    %7D%0A    %0A
     

remove unused methods from API