/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package dowser.model;

import java.io.File;
import java.io.FileNotFoundException;
import java.util.Scanner;

/**
 *
 * @author Chetan Pawgi
 */
public abstract class ModelParser {

	private static String checkClassName(String className) {
		if (className.endsWith("class")) {
			className = className.substring(0, className.length() - "class".length());
		}
		return className;
	}

	public static DomainModel parseModel(String fileName) throws FileNotFoundException {
		DomainModel model = new DomainModel();
		Scanner sc = new Scanner(new File(fileName));
		Class curClass = null;
		while (sc.hasNext()) {
			String line = sc.nextLine();
			String[] arrLine = line.split(" ");
			if (line.startsWith("class")) {
				String className = checkClassName(arrLine[1]);
				if (!model.containsClass(className)) {
					model.addClass(new Class(className));
				}
				curClass = model.getClass(className);
			} else if (line.startsWith("method")) {
				String method = arrLine[1];
				curClass.addOperation(method);
			} else if (line.startsWith("attribute")) {
				String attribute = arrLine[1];
				curClass.addAttribute(attribute);
			} else if (line.startsWith("@superclass")) {
				String superClassName = checkClassName(arrLine[1]);
				if (!model.containsClass(superClassName)) {
					model.addClass(new Class(superClassName));
				}
				Class superClass = model.getClass(superClassName);
				if (superClass.equals(curClass)) {
					throw new IllegalStateException("Class " + curClass.getName() + " can't inherit itself");
				}
				superClass.addSubClass(curClass);
			} else if (line.startsWith("@aggregation")) {
				String compositeClassName = checkClassName(arrLine[1]);
				if (!model.containsClass(compositeClassName)) {
					model.addClass(new Class(compositeClassName));
				}
				Class compositeClass = model.getClass(compositeClassName);
				Relation relation = new Relation("#aggregation");
				relation.addParticipant(curClass, "composite", "0..1");
				relation.addParticipant(compositeClass, "sub-component", "0..*");
				model.addRelation(relation);
			} else if (line.startsWith("@association")) {
				String otherClassName = checkClassName(arrLine[2]);
				if (!model.containsClass(otherClassName)) {
					model.addClass(new Class(otherClassName));
				}
				Class otherClass = model.getClass(otherClassName);
				Relation relation = new Relation(arrLine[1]);
				relation.addParticipant(curClass, "source", "1");
				relation.addParticipant(otherClass, "target", "1");
				model.addRelation(relation);
			}
		}
		sc.close();
		return model;
	}
}
