(*********************************************************************************)

(*                Cameleon                                                       *)
(*                                                                               *)
(*    Copyright (C) 2005,2006 Institut National de Recherche en Informatique     *)
(*    et en Automatique. All rights reserved.                                    *)
(*                                                                               *)
(*    This program is free software; you can redistribute it and/or modify       *)
(*    it under the terms of the GNU Library General Public License as            *)
(*    published by the Free Software Foundation; either version 2 of the         *)
(*    License, or  any later version.                                            *)
(*                                                                               *)
(*    This program is distributed in the hope that it will be useful,            *)
(*    but WITHOUT ANY WARRANTY; without even the implied warranty of             *)
(*    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the              *)
(*    GNU Library General Public License for more details.                       *)
(*                                                                               *)
(*    You should have received a copy of the GNU Library General Public          *)
(*    License along with this program; if not, write to the Free Software        *)
(*    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA                   *)
(*    02111-1307  USA                                                            *)
(*                                                                               *)
(*    Contact: Maxence.Guesdon@inria.fr                                          *)
(*                                                                               *)
(*********************************************************************************)


(** Types. *)


type cvs_status =
  | Up_to_date 
    (** The file is identical with the latest revision in the repository for the branch in use. *)

  | Locally_modified 
    (** You have edited the file, and not yet committed your changes. *)

  | Locally_added 
    (** You have added the file with add, and not yet committed your changes. *)

  | Locally_removed 
    (** You have removed the file with remove, and not yet committed your changes. *)

  | Needs_checkout 
    (** Someone else has committed a newer revision to the repository. The name is slightly misleading; you will ordinarily use update rather than checkout to get that newer revision. *)

  | Needs_Patch 
    (** Like Needs Checkout, but the CVS server will send a patch rather than the entire file. Sending a patch or sending an entire file accomplishes the same thing. *)

  | Needs_Merge 
    (** Someone else has committed a newer revision to the repository, and you have also made modifications to the file. *)

  | Conflicts_on_merge 
                
                (** This is like Locally Modified, except that a previous update command gave a conflict. If you have not already done so, you need to resolve the conflict as described in 10.3 Conflicts example. *)

  | Unknown 
    (** CVS doesn't know anything about this file. For example, you have created a new file and have not run add. *)



type update_action =
    U 
     (** The file was brought up to date with respect to the repository. This is done for any file that exists in the repository but not in your source, and for files that you haven't changed but are not the most recent versions available in the repository. *)

  | P 
    (** Like `U', but the CVS server sends a patch instead of an entire file. These two things accomplish the same thing. *)

  | A 
    (** The file has been added to your private copy of the sources, and will be added to the source repository when you run commit on the file. This is a reminder to you that the file needs to be committed. *)

  | R 
    (** The file has been removed from your private copy of the sources, and will be removed from the source repository when you run commit on the file. This is a reminder to you that the file needs to be committed. *)

  | M 
    (** The file is modified in your working directory. *)

  | C 
    (** A conflict was detected while trying to merge your changes to file with changes from the source repository. *)

  | QM 
    (** file is in your working directory, but does not correspond to anything in the source repository. *)


(** Information on a file handled by CVS. *)

type cvs_info = {
    cvs_file : string ; 
        (** absolute file name *)

    cvs_status : cvs_status ; 
    cvs_work_rev : string ; 
        (** working revision *)

    cvs_rep_rev : string ; 
        (** repository revision *)

    cvs_date_string : string ; 
        (** the date as displayed by cvs status *)

    cvs_date : float ; 
        (** the date of the last time we got the information on this file *)

  } 

type cvs_revision = {
    rev_number : int list ;
    rev_author : string ;
    rev_date : string ;
    rev_comment : string ;
  } 

(** To report failure while executing a cvs command. *)

exception CvsFailure of string

(** To report partial failure (e.g. for one file among various files) while executing a cvs command. *)

exception CvsPartFailure of string

(** To indicate what character in a tag is incorrect. *)

exception Tag_error of int



(** *)

let string_of_status s =
  match s with
  | Up_to_date -> "Up-to-date"
  | Locally_modified -> "Locally Modified"
  | Locally_added -> "Locally Added"
  | Locally_removed -> "Locally Removed"
  | Needs_checkout -> "Needs Checkout"
  | Needs_Patch -> "Needs Patch"
  | Needs_Merge -> "Needs Merge"
  | Conflicts_on_merge -> "File had conflicts on merge"
  | Unknown -> "Unknown"

(** *)

let status_of_string s =
  match s with
  | "Up-to-date" -> Up_to_date 
  | "Locally Modified" -> Locally_modified
  | "Locally Added" -> Locally_added
  | "Locally Removed" -> Locally_removed
  | "Needs Checkout" -> Needs_checkout
  | "Needs Patch" -> Needs_Patch
  | "Needs Merge" -> Needs_Merge
  | "File had conflicts on merge" -> Conflicts_on_merge
  | "Unknown" -> Unknown
  | _ -> raise (CvsFailure (Ocvs_messages.error_status_string s))

let update_action_of_string s =
  match s with
    "U" -> U
  | "P" -> P
  | "A" -> A
  | "R" -> R
  | "M" -> M
  | "C" -> C
  | "?" -> QM
  | _ -> raise (CvsFailure (Ocvs_messages.error_update_action_string s))

(** Dump of a cvs_info structure. *)

let dump_cvs_info ci =
  print_string
    ("{ cvs_file = \""^ci.cvs_file^"\" ;\n"^
     "  cvs_status = "^(string_of_status ci.cvs_status)^" ;\n"^
     "  cvs_work_rev = \""^ci.cvs_work_rev^"\" ;\n"^
     "  cvs_rep_rev = \""^ci.cvs_rep_rev^"\" ;\n"
     "  cvs_date_string = "^ci.cvs_date_string^" ;\n"^
     "  cvs_date = "^(string_of_float ci.cvs_date)^" ;\n"^
     "}\n"
    )