package rmi.rmiSynth.lex;

// target:
// rmi.rmiSynth.lex.Generator


import graphics.raytracer.DoImage;
import graphics.raytracer.Main;
import rmi.rmiSynth.LocalClient;

import java.awt.*;

/**
 * Class rmi.rmiSynth.Generator generates classes for accessing remote server
 * @author Roman Yedokov
 * @version 1.1, D. Lyon
 */

public class Generator {

  private boolean onlyPublic = true;        //Output only public members
  private boolean withMain = false;     //Provide main method
  private boolean noMain = true;            //Do not provide main method
  private boolean withDelegate = true;  //Include cutils.delegate
  private boolean noDelegate = false;       //Do not include cutils.delegate
  private String s;                     //Output string
  private FileSaver fs = new FileSaver();

  public static void test1() {

    String serverClassName = "DoImageServer";       //RMI Server class name
    String serverInterfaceName = "DoImageInterface";        //RMI Interface name
    String exampleClientName = "DoImageClient";     //RMI Client class name

    LocalClient sequentialClass =
        new LocalClient();
    DoImage serverClass =
        new DoImage(new Dimension());

    synthesizeSource(
        serverInterfaceName,
        serverClass,
        serverClassName,
        exampleClientName,
        sequentialClass);
  }

  public static void main(String args[]) {

    String serverClassName = "DoImageServer";       //RMI Server class name
    String serverInterfaceName = "DoImageInterface";        //RMI Interface name
    String exampleClientName = "DoImageClient";     //RMI Client class name

    DoImage serverClass = new DoImage(new Dimension(200, 200));
    Main clientClass = new Main();

    synthesizeSource(
        serverInterfaceName,
        serverClass,
        serverClassName,
        exampleClientName,
        clientClass);
  }

  private static void synthesizeSource(String serverInterfaceName,
                                       Object serverClass,
                                       String serverClassName,
                                       String exampleClientName,
                                       Object sequentialClass) {
    Generator generator = new Generator();
    generator.createInterface(serverInterfaceName, serverClass);
    generator.createServer(serverInterfaceName, serverClassName, serverClass);
    //Comment out next line if you don't need to generate client
    generator.createClient(
        serverInterfaceName,
        serverClassName,
        exampleClientName,
        sequentialClass);
  }

  /**
   * Generates RMI interface out of a class
   * @param anInterface Designates that output source file will be an interface
   * @param newServerInter Name for new interface
   * @param lbs Source class out of which RMI interface will be generated
   */
  public void createInterface(String newServerInter, Object sequentialClass) {
    boolean isInterface = true;
    LexBase lb = new LexBase(isInterface, newServerInter, sequentialClass);
    Transform.toRMIInterface(lb);
    s = lb.toString(onlyPublic, withMain, withDelegate);
    System.out.println(s);
    fs.createFile(s, newServerInter);

  }

  /**
   * Generates RMI server class out of a class
   * @param aClass Designates that output source file will be a class
   * @param newServerInter Interface name output class should implement
   * @param newServerClass Name for new class
   * @param lbs Source class out of which RMI server class will be generated
   */
  public void createServer(
      String newServerInter,
      String newServerClass,
      Object sequentialClass) {
    boolean isClass = true;
    LexBase lb = new LexBase(isClass, newServerClass, sequentialClass);
    Transform.toRMIServer(lb, newServerInter, newServerClass);
    s = lb.toString(onlyPublic, withMain, withDelegate);
    System.out.println(s);
    fs.createFile(s, newServerClass);

  }

  /**
   * Generates template for RMI client class out of a class
   * @param aClass Designates that output source file will be a class
   * @param newServerInter Interface name output class should instanciate
   * @param newServerClass Class name output class should connect to
   * @param newClientClass Name for new class
   * @param lbc Source class out of which RMI client class will be generated
   */
  public void createClient(
      String newServerInter,
      String newServerClass,
      String newClientClass,
      Object sequentialClass) {
    boolean isClass = true;
    LexBase lb = new LexBase(isClass, newClientClass, sequentialClass);
    Transform.toRMIClient(lb, newServerInter, newServerClass, newClientClass, "\"localhost\"");
    s = lb.toString(onlyPublic, noMain, noDelegate);
    System.out.println(s);
    fs.createFile(s, newClientClass);
  }

}