/*---------------------------------------------------------------------------*\
**$Author: antanas $
**$Date: 2023-05-06 21:53:35 +0300 (Sat, 06 May 2023) $
**$Revision: 603 $
**$URL: svn+ssh://www.crystallography.net/home/coder/svn-repositories/smiles-scripts/tags/v0.4.0/src/cdksdf2inchi.java $
\*---------------------------------------------------------------------------*/

// This CLI Java program reads an SDF and converts it to an InChI string.

// Example taken from:

// Spjuth, O.; Berg, A.; Adams, S. & Willighagen, E. L.  Applications
// of the InChI in cheminformatics with the CDK and Bioclipse Journal
// of Cheminformatics, Springer Science and Business Media LLC, 2013,
// 5, DOI: 10.1186/1758-2946-5-14

import org.openscience.cdk.ChemFile;
import org.openscience.cdk.aromaticity.Aromaticity;
import org.openscience.cdk.aromaticity.ElectronDonation;
import org.openscience.cdk.AtomContainer;
import org.openscience.cdk.aromaticity.Kekulization;
import org.openscience.cdk.config.AtomTypeFactory;
import org.openscience.cdk.graph.CycleFinder;
import org.openscience.cdk.graph.Cycles;
import org.openscience.cdk.graph.rebond.RebondTool;
import org.openscience.cdk.interfaces.*;
import org.openscience.cdk.io.ISimpleChemObjectReader;
import org.openscience.cdk.io.MDLV2000Reader;
import org.openscience.cdk.io.MDLV3000Reader;
import org.openscience.cdk.silent.SilentChemObjectBuilder;
import org.openscience.cdk.inchi.InChIGeneratorFactory;
import org.openscience.cdk.inchi.InChIGenerator;

// https://www.tutorialspoint.com/log4j/log4j_logging_levels.htm :
// need this import to set log levels:
import org.apache.log4j.*;
import net.sf.jnati.deploy.artefact.ConfigManager;
import net.sf.jnati.deploy.repository.ClasspathRepository;
import net.sf.jnati.deploy.repository.LocalRepository;
import net.sf.jnati.deploy.artefact.ManifestReader;
import net.sf.jnati.deploy.NativeLibraryLoader;
import net.sf.jnati.deploy.NativeArtefactLocator;

import java.io.FileReader;
import java.util.Hashtable;

import static net.crystallography.helpers.cdk.OrthogonaliseAtomCoordinates.computeOrthogonalCoordinates;
import static org.openscience.cdk.tools.manipulator.AtomContainerManipulator.percieveAtomTypesAndConfigureAtoms;
import static org.openscience.cdk.tools.manipulator.AtomContainerManipulator.removeHydrogens;
import static org.openscience.cdk.tools.manipulator.AtomContainerManipulator.suppressHydrogens;

@SuppressWarnings("ALL")
public class cdksdf2inchi {

    static OptionValue suppressHydrogensOption = new OptionValue();
    static OptionValue readMDLV3000Option = new OptionValue();

    static Option options[] = {
        new Option( "-2", "--mdl2000-input", OptionType.OT_BOOLEAN_FALSE,
                    readMDLV3000Option ),
        new Option( "-3", "--mdl3000-input", OptionType.OT_BOOLEAN_TRUE,
                    readMDLV3000Option ),

        new Option( "-h", "--suppress-hydrogens", OptionType.OT_BOOLEAN_TRUE,
                    suppressHydrogensOption ),
        new Option( "-h-", "--dont-suppress-hydrogens", OptionType.OT_BOOLEAN_FALSE,
                    suppressHydrogensOption ),
        new VersionOption    ( null, "--version", OptionType.OT_FUNCTION ),
        new CDKSdf2InChIHelp ( null, "--help",    OptionType.OT_FUNCTION ),
    };

    private static final String progName = CDKSdf2InChIHelp.progName;

    private static org.apache.log4j.Logger configManagerLog = Logger.getLogger(net.sf.jnati.deploy.artefact.ConfigManager.class);
    private static org.apache.log4j.Logger classpathRepositoryLog = Logger.getLogger(net.sf.jnati.deploy.repository.ClasspathRepository.class);
    private static org.apache.log4j.Logger localRepositoryLog = Logger.getLogger(net.sf.jnati.deploy.repository.LocalRepository.class);
    private static org.apache.log4j.Logger manifestReaderLog = Logger.getLogger(net.sf.jnati.deploy.artefact.ManifestReader.class);
    private static org.apache.log4j.Logger nativeLibraryLoaderLog = Logger.getLogger(net.sf.jnati.deploy.NativeLibraryLoader.class);
    private static org.apache.log4j.Logger nativeArtefactLocatorLog = Logger.getLogger(net.sf.jnati.deploy.NativeArtefactLocator.class);
    
    @SuppressWarnings("SingleStatementInBlock")
    public static void main(String[] argv ) {
        // https://www.tutorialspoint.com/log4j/log4j_logging_levels.htm :
        // Set log level to warnings:
        configManagerLog.setLevel(Level.WARN);
        classpathRepositoryLog.setLevel(Level.WARN);
        localRepositoryLog.setLevel(Level.WARN);
        manifestReaderLog.setLevel(Level.WARN);
        nativeLibraryLoaderLog.setLevel(Level.WARN);
        nativeArtefactLocatorLog.setLevel(Level.WARN);

        int exitStatus = 0;
        
        // Suppress explicit hydrogens by default:
        suppressHydrogensOption.bool = true;

        String filenames[] = null;
        try {
            filenames = SOptions.get_options( argv, options );
        }
        catch (SOptionsException e) {
            System.err.println( progName + ": " + e.getMessage() );
            System.exit(1);
        }

        if( filenames == null || filenames.length == 0 ) {
            filenames = new String[] { "-" };
        }
        for( String filename : filenames ) {
            try {
                ISimpleChemObjectReader reader;
                if (filename.equals("-")) {
                    if( readMDLV3000Option.bool == true ) {
                        reader = new MDLV3000Reader(System.in);
                    } else {
                        reader = new MDLV2000Reader(System.in);
                    }
                } else {
                    if( readMDLV3000Option.bool == true ) {
                        reader = new MDLV3000Reader(new FileReader(filename));
                    } else {
                        reader = new MDLV2000Reader(new FileReader(filename));
                    }
                }

                IAtomContainer container = reader.read(new AtomContainer());
                assert container != null;

                if( suppressHydrogensOption.bool == true ) {
                    suppressHydrogens(container);
                }

                InChIGeneratorFactory factory =
                    InChIGeneratorFactory.getInstance();

                InChIGenerator generator;
                if( suppressHydrogensOption.bool == true ) {
                    generator = factory.getInChIGenerator( container );
                } else {
                    generator = factory.getInChIGenerator( container, "FixedH" );
                }


                System.out.print( generator.getInchi() );

                String titleKey = "cdk:Title";
                if( container.getProperties().containsKey(titleKey) ) {
                    System.out.print("\t" + container.getProperties().get(titleKey));
                }
                System.out.println();
                
            } // try
            catch(Exception e) {
                System.err.println( progName + ": " + "WARNING, " + e +
                                    " in file '" + filename + "'" );
                exitStatus = 1;
            }
        } // for
        System.exit(exitStatus);
    }
}
