/*
 * Copyright (c) 2002-2010 JSCAPE
 * 1147 S. 53rd Pl., Mesa, Arizona, 85206, U.S.A.
 * All rights reserved.
 *
 * This software is the confidential and proprietary information of
 * JSCAPE. ("Confidential Information").  You shall not disclose such
 * Confidential Information and shall use it only in accordance with
 *  the terms of the license agreement you entered into with JSCAPE.
 */

package com.jscape.inet.ftp;

import com.jscape.util.IOTools;

import java.io.BufferedReader;
import java.io.IOException;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;

/**
 * @author Alex Usun
 */
@SuppressWarnings("unchecked")
public class MvsParser
        implements FtpFileParser {

    private static final String[] DATE_PATTERNS = {
            "yyyy/MM/dd",
            "MM/dd/yy",
    };

    public Enumeration parse(BufferedReader in)
            throws IOException {
        try {
            skipTableHeader(in);
            List records = readRecords(in);
            Vector files = convertToFiles(records);

            return files.elements();
        } catch (Exception e) {
            throw IOTools.ioException(e);
        }
    }

    public Date getFileDate(String date)
            throws ParseException {
        for (int i = 0; i < DATE_PATTERNS.length; ++i) {
            try {
                return parseDate(date, DATE_PATTERNS[i]);
            } catch (Exception e) {
                // ignore
            }
        }

        return null;
    }

    public Date getDateTime(FtpFile file)
            throws ParseException {
        return getFileDate(file.getDate());
    }

    private void skipTableHeader(BufferedReader in)
            throws IOException {
        in.readLine();
    }

    private List readRecords(BufferedReader in)
            throws IOException {
        List records = new LinkedList();
        String line;
        while (((line = in.readLine()) != null)) {
            MvsFileRecord record = parseLine(line);
            records.add(record);
        }

        return records;
    }

    private MvsFileRecord parseLine(String line) {
        String[] elements = line.split(" +");
        return new MvsFileRecord(line,
                                 elements[0],
                                 elements[1],
                                 elements[2],
                                 elements[3],
                                 elements[4],
                                 elements[5],
                                 elements[6],
                                 elements[7],
                                 elements[8],
                                 elements[9]);
    }

    private Vector convertToFiles(List records) {
        Vector files = new Vector();
        for (Iterator i = records.iterator(); i.hasNext(); ) {
            MvsFileRecord record = (MvsFileRecord) i.next();
            FtpFile file = record.asFile();
            file.setFtpFileParser(this);
            files.add(file);
        }

        return files;
    }

    private Date parseDate(String date, String pattern)
            throws Exception {
        return new SimpleDateFormat(pattern).parse(date);
    }

    public static class MvsFileRecord {

        public final String line;
        public final String volume;
        public final String unit;
        public final String referred;
        public final String ext;
        public final String used;
        public final String recfm;
        public final String lrecl;
        public final String blksize;
        public final String dsorg;
        public final String dsname;

        public MvsFileRecord(String line,
                             String volume,
                             String unit,
                             String referred,
                             String ext,
                             String used,
                             String recfm,
                             String lrecl,
                             String blksize,
                             String dsorg,
                             String dsname) {
            this.line = line;
            this.volume = volume;
            this.unit = unit;
            this.referred = referred;
            this.ext = ext;
            this.used = used;
            this.recfm = recfm;
            this.lrecl = lrecl;
            this.blksize = blksize;
            this.dsorg = dsorg;
            this.dsname = dsname;
        }

        public FtpFile asFile() {
            return new FtpFile(this.dsname, size(), "", "", "", "", "", false, false, "", 0, this.line);
        }

        public String toString() {
            return "MvsFileRecord {"
                    + "volume='" + this.volume + '\''
                    + ", unit='" + this.unit + '\''
                    + ", referred='" + this.referred + '\''
                    + ", ext='" + this.ext + '\''
                    + ", used='" + this.used + '\''
                    + ", recfm='" + this.recfm + '\''
                    + ", lrecl='" + this.lrecl + '\''
                    + ", blksize='" + this.blksize + '\''
                    + ", dsorg='" + this.dsorg + '\''
                    + ", dsname='" + this.dsname + '\''
                    + '}';
        }

        private long size() {
            try {
                return Long.parseLong(this.blksize);
            } catch (NumberFormatException e) {
                return 0;
            }
        }
    }
}
